00:00:16.800
Welcome. My name is Wade Winningham and
00:00:18.880
I'm a principal developer at Power Home
00:00:20.800
Remodeling.
00:00:27.680
So from the people here who are not from
00:00:29.920
power,
00:00:31.439
uh how many of you guys have worked on
00:00:33.920
the same Ruby application for like over
00:00:36.239
five years?
00:00:38.239
Wow, that's that's a few but not as many
00:00:40.000
as I thought. So how about 10?
00:00:42.719
Anybody longer than that? That's Wow,
00:00:45.840
just a couple. Wow. So
00:00:48.960
I've been working on P's application for
00:00:51.440
18 years now. We started in 2007. So,
00:00:54.320
this is what literally my 18th year with
00:00:56.320
it. And I'm here today to tell you a
00:00:59.280
little about Power um and Nitro, the app
00:01:03.199
that powers our business. Um a policy
00:01:06.960
that's led to its growth that's a little
00:01:08.640
bit controversial. Um how we modularized
00:01:11.600
it and then showcase some of our open
00:01:13.280
source projects that uh maybe you guys
00:01:15.280
can get uh into your own applications.
00:01:19.200
So, Power's been in business since 1992.
00:01:22.400
So, what does Power actually do? We sell
00:01:25.680
windows, door, siding, and solar
00:01:27.759
solutions to existing homeowners. Um,
00:01:30.960
Power is actually a very employee
00:01:33.040
focused company. As Jenny Gay said
00:01:34.640
earlier, we say we don't hire people to
00:01:37.040
sell windows, but rather we sell windows
00:01:38.960
to hire people. And when someone asks
00:01:41.439
where I work, and I tell them I work in
00:01:43.600
a place that sells windows, doors, and
00:01:46.240
siding, I can see on their face if this
00:01:48.560
is where they think I work.
00:01:52.079
Um,
00:01:54.079
guaranteed that's the reaction I get
00:01:55.680
from people. Um, now these photos are
00:01:57.920
from one of our warehouses, but it's not
00:01:59.840
where we actually have office space. We
00:02:02.159
do have an headquarters that's down the
00:02:04.159
road here outside of Philadelphia. Um,
00:02:06.320
it is in actually a former power plant,
00:02:08.640
which is kind of cool. And, um, we do
00:02:11.200
have a lot of offices around the
00:02:12.640
country. Um, and our HQ
00:02:16.239
is the base of operations for our
00:02:18.720
business technology team. many of them
00:02:20.800
are here. Um, we are like a tech company
00:02:23.760
with empowered where we build Nitro and
00:02:26.879
we think of it as the operating system
00:02:28.800
for our business. It's primarily built
00:02:31.599
with Ruby, Rails, MySQL, some Postgress
00:02:35.519
mostly for GIS capabilities, TypeScript,
00:02:38.560
React and Swift for our mobile
00:02:39.920
applications.
00:02:41.760
Now, Nitro started on Rails 1.23
00:02:46.640
like on 2007. I guess that was the
00:02:49.040
current version back then. Uh so we've
00:02:51.120
been through quite a number of Ruby and
00:02:52.640
Rails upgrades over the years. And this
00:02:55.360
is literally the timeline of all our
00:02:57.280
upgrades for Ruby and Rails over those
00:02:59.040
years. It's something we keep as part of
00:03:01.040
presentations that we give even today.
00:03:03.440
And I just wanted to give a big shout
00:03:05.040
out to fast ruby.io andabs who's helped
00:03:07.840
us through a lot of the upgrades from
00:03:09.680
four through six which were some painful
00:03:11.760
ones for us but uh they were a huge help
00:03:13.599
and so we heartfeltly recommend them
00:03:16.159
whenever we can.
00:03:18.879
Now, when we started back in 2007, Power
00:03:22.640
had nothing but spreadsheets and a
00:03:24.879
single user app that was written in
00:03:26.879
Microsoft Access. Um, and it just was
00:03:30.080
not uh keeping track with them. They
00:03:33.280
literally had to yell down the hall to
00:03:34.879
get people to get out of the app to make
00:03:36.400
any changes.
00:03:38.239
And um while that was a pain, one of the
00:03:40.560
biggest pains was that the sales
00:03:43.040
director would spend nights and weekends
00:03:45.440
updating individual spreadsheets for
00:03:47.519
sales rep statistics so that he could
00:03:49.599
mail them out every single morning to
00:03:51.200
all of his reps. Um that wasn't really a
00:03:54.720
particularly good use of his time. So um
00:03:58.319
they needed a way to basically you know
00:04:00.319
centralize that data and make it
00:04:01.760
accessible and scalable which resulted
00:04:04.879
in this their very very first page of a
00:04:07.599
Ruby on Rails app. It was me starting
00:04:10.000
this thing and within like a month they
00:04:12.159
had this up and running and they were
00:04:13.599
extremely happy. Um now that was really
00:04:16.720
small but you know now anybody could log
00:04:19.919
in and see their stats on any day and
00:04:22.240
the data was imported from their
00:04:23.600
existing system. So, it was really bare
00:04:25.440
bones, but it kind of uh lit a fire
00:04:28.000
under them. Now, looking at that same
00:04:31.040
page today, it's got a lot of different
00:04:33.199
things on it and it's expanded quite a
00:04:35.360
bit and uh we just basically molded it
00:04:38.479
over the years uh to keep up to date
00:04:40.400
with the increasing demands of the
00:04:42.400
business and the employees.
00:04:45.280
Now, that obviously went through a lot
00:04:47.600
of growth. Um, and our app overall to
00:04:50.720
drive the entire business has grown a
00:04:52.479
lot over the years. And from that first
00:04:54.800
page to today, Nitro currently has over
00:04:57.680
three million lines of code of Ruby
00:04:59.680
code. Um, and that's not including some
00:05:02.240
apps that we've split out of our
00:05:03.440
monolith. Um, and while it's grown
00:05:06.000
simply by adding features throughout the
00:05:07.919
entire business, I want to talk today
00:05:10.720
about a policy we have that has helped
00:05:12.240
us grow about to a code base this size.
00:05:15.280
And whenever it's brought up in
00:05:16.639
candidate interviews and with people we
00:05:18.720
talk to, it causes them to raise an
00:05:20.720
eyebrow. And that's our policy on build
00:05:23.280
versus buy. Um, now this isn't a strict
00:05:26.800
rule, but when it makes sense for the
00:05:28.479
business, we prefer to build something
00:05:30.800
ourselves rather than buy it. Now, this
00:05:34.080
can be controversial. U, the Sidekick
00:05:36.479
Wiki has a page all about why building
00:05:38.400
something yourself is going to cost
00:05:40.400
significantly more than buying it. And
00:05:42.560
in the context presented, Mike's right.
00:05:46.639
But buying a service or software isn't
00:05:48.960
always the best for your business.
00:05:52.320
It can be a bit of a minefield um with
00:05:55.360
confusing pricing plans that initially
00:05:57.280
sound great but result in outrageously
00:06:00.240
large bills later down the road.
00:06:03.199
We like to say we put our culture in
00:06:05.039
code. And when you build an app for your
00:06:07.520
business, you have to learn how your
00:06:09.840
business truly works.
00:06:11.840
You get knowledge you'd never gain by
00:06:13.840
trying to squeeze your app into somebody
00:06:15.600
else's. You get control over what your
00:06:18.240
business needs and when they need it.
00:06:20.479
And you're not making processes suffer
00:06:22.319
because of generalized software. And
00:06:24.960
your business is going to grow. And as
00:06:27.600
you scale, the services you use
00:06:29.440
typically will cost much more as you do.
00:06:33.600
Surprise. Price increases from outside
00:06:35.440
systems can be attacks on your on your
00:06:37.440
business. And for a business our size, I
00:06:39.600
could add hundreds of thousands of
00:06:41.120
dollars to cost all the support features
00:06:43.280
we never asked for or even need in some
00:06:45.280
cases.
00:06:47.440
An example of what I'm talking about is
00:06:49.039
around job applicants. Now, these are
00:06:51.759
some screenshots of just a handful of
00:06:53.360
sites that I found of companies that
00:06:55.600
help you manage your recruiting process.
00:06:58.240
We used to use one of them, but then one
00:07:01.120
day we got an email saying, um, we're
00:07:04.160
going out of business in 30 days. uh get
00:07:06.639
your data and so long. So we didn't feel
00:07:11.199
like getting put into that same
00:07:12.479
situation again with another company.
00:07:15.280
And so since our trust was shot,
00:07:19.120
fortunately we were able to pay them to
00:07:20.960
keep their service running while we
00:07:22.319
built our own solution.
00:07:24.720
And in six months with a team of three
00:07:26.560
developers with Ruby on Rails, we built
00:07:28.800
our own recruiting system that's now
00:07:31.120
better for us, more tightly integrated
00:07:33.280
with our systems. It's better than
00:07:35.280
anything we could buy and we continue to
00:07:36.960
make it better every day. We're not
00:07:39.520
paying for features we'd never use. It's
00:07:41.840
exactly what we need and we own our own
00:07:44.800
data and obviously with uh job applicant
00:07:47.520
data, candidate information, um there's
00:07:51.280
security concerns around that. So,
00:07:52.639
keeping track of our own data is we feel
00:07:54.639
more secure about that and we don't
00:07:56.720
worry about us going out of business.
00:07:59.039
Recruiting is just another part of
00:08:00.400
Nitro.
00:08:02.319
Another example of a place that went out
00:08:04.240
of business is Pivotal Tracker. Did
00:08:06.639
anybody ever use Pivotal Tracker? A
00:08:09.360
number of you. Um, so we used it a long
00:08:12.080
time ago. Um, and if you I guess if
00:08:15.280
anybody's there, this they don't even
00:08:16.960
have a site anymore. So hopefully you're
00:08:18.479
able to get your data. Um, but based on
00:08:21.120
past experience, we weren't very
00:08:22.720
inclined to just move to a different
00:08:24.080
product. Does anybody here use Jira now?
00:08:27.840
Wow. A few. Do do you like it?
00:08:31.039
I don't see any hands. Wow.
00:08:34.000
So, yeah. So, you know, and even if you
00:08:37.919
haven't used Jur, do you have work in a
00:08:39.919
place where one department uses one tool
00:08:41.519
and another uses something else? Like
00:08:43.599
one place uses a Google doc, another
00:08:45.839
maybe a sauna in another department.
00:08:49.200
I mean, that's that's just I don't know
00:08:51.600
just not very consistent. So instead of
00:08:54.000
moving to another service, we built
00:08:55.600
runway and had our first version up in
00:08:58.320
Ruby on Rails with four devs and four in
00:09:00.720
yeah four months. Um and outside of the
00:09:03.920
whole trust issue, why build it? Um you
00:09:07.360
know what we do is we think that what we
00:09:11.200
use to plan and build our software
00:09:13.120
contains really important intellectual
00:09:15.040
property that we don't want to lose. So
00:09:18.320
and our soft we're on the last track
00:09:21.200
now. We wanted our entire business to
00:09:23.519
learn to use agile. So using the same
00:09:25.200
tool across the company um has helped
00:09:28.240
teach everybody how to work with agile
00:09:30.880
the same way as our business technology
00:09:32.399
teams. Different departments don't use
00:09:35.040
their own software and we never have to
00:09:37.040
buy more licenses.
00:09:38.959
Now it's not nearly ready yet, but we do
00:09:41.120
have an eye towards open sourcing this
00:09:42.560
one day.
00:09:45.120
Now we don't exclusively build software
00:09:47.440
from scratch. We do use and support open
00:09:49.440
source. Um, the current version of our
00:09:52.240
messaging app, which is called Connect,
00:09:53.680
is built on top of Matrix, which is open
00:09:56.320
source. So, why not use Slack or
00:09:58.640
Discord? We're a really communicative
00:10:01.440
and distributed business, and we want
00:10:03.760
secure messaging and something tightly
00:10:06.160
integrated with our systems.
00:10:09.120
For example, Power has an awesome people
00:10:10.800
experience department. Um, and they plan
00:10:13.279
a lot of events during the year and more
00:10:15.440
events than there are weeks in the year.
00:10:17.519
And anything around events is
00:10:18.800
customization. Most messaging clients
00:10:21.040
don't support without a lot of
00:10:22.320
development effort already. So Slack and
00:10:24.800
Discord are great, but rolling our own
00:10:26.560
allows us to keep control of our own
00:10:28.000
data and build the features we need.
00:10:31.040
And we even host in our own cloud on our
00:10:33.120
own data data centers. We don't use
00:10:35.200
Azure or Google or AWS.
00:10:38.320
Is it easier to use them? Probably. They
00:10:41.279
just come with all those confusing
00:10:42.560
pricing models I mentioned earlier. And
00:10:44.640
the slightest changes of those pricing
00:10:46.480
models can have a really serious huge
00:10:48.720
impact on your budget. And if you're
00:10:50.959
wanting to scale your business, we think
00:10:53.040
it's better to hire smart people than to
00:10:55.440
have other people sell you theirs. We
00:10:58.079
kind of see hosting services as their
00:10:59.680
own tax. You host your software with
00:11:02.560
them, even software you write, and then
00:11:05.120
they charge you for it. That's kind of
00:11:07.519
our view and why we host our own stuff.
00:11:10.560
Now, we don't do this for everything. If
00:11:12.320
it's not core to our business, we'll
00:11:14.480
certainly use outside services that best
00:11:16.560
suit our needs. In a lot of these cases,
00:11:18.959
it's best for them it best for them to
00:11:20.720
be hosted outside of our infrastructure
00:11:22.240
anyway, so if something goes down, we
00:11:24.160
still have access to information to help
00:11:25.920
us diagnose what's happening.
00:11:29.200
We like to invest in the people and
00:11:30.880
applications that give us customized
00:11:32.480
solutions where we own our own data.
00:11:35.680
Does this cost more long term? Likely,
00:11:38.720
but with less surprises. And although
00:11:41.200
Rails allows us to deliver relatively
00:11:43.200
quickly, you still need time to develop
00:11:46.079
and m and maintain, you know, for
00:11:48.399
ongoing feature development,
00:11:50.880
but but we own our own destiny and we're
00:11:52.880
investing it in ourselves rather than
00:11:54.480
organizations that don't even know us.
00:11:57.600
Now, is this for everybody? Of course
00:11:59.360
not. Um, you have to do what makes sense
00:12:01.839
for you and consider the risks. We don't
00:12:04.320
just jump out of the gate and start
00:12:05.680
building stuff, but it's always on the
00:12:07.200
table. But if you're growing, then you
00:12:09.920
are going to be the best at growing both
00:12:11.760
your business and your software.
00:12:14.800
Now, after many years of building and
00:12:16.800
growing, Nitro grew into a monolith.
00:12:20.560
A large code base leads to a lot of
00:12:22.399
problems. And at our worst point, our CI
00:12:24.880
builds literally took four and a half
00:12:26.800
hours for a single build. Not to mention
00:12:29.519
problems with code organization.
00:12:32.399
So, who's here heard of Packwork?
00:12:35.760
Uh, good number of people.
00:12:38.079
if you haven't, it's all about
00:12:39.440
compartmentalizing large monoliths like
00:12:41.760
Nitro. However, packwork wasn't a thing
00:12:44.560
when we needed to start doing this. At
00:12:47.279
that point, um Stefan Hogaman's original
00:12:50.240
book on the topic was component-based
00:12:52.399
Rails applications or Cobra.
00:12:55.440
It was in beta, but we dove into it
00:12:57.920
anyway. Um does anybody use or have an
00:13:02.160
application written with, you know, as a
00:13:04.399
component-based Rails application? Wow,
00:13:07.920
a couple. I'm really surprised. That's
00:13:10.160
awesome. So,
00:13:13.440
I asked because I met Stefan last year
00:13:15.600
at Railscom and he seemed really
00:13:17.920
surprised and excited to see what we've
00:13:19.920
done with Cobra.
00:13:22.480
So, by the t time packs was introduced,
00:13:26.240
we had already had years behind us with
00:13:28.079
Cobra. And while most seem to have
00:13:30.560
abandoned it, and obviously there's, you
00:13:32.240
know, a few, you know, stragglers here,
00:13:34.320
that's awesome.
00:13:36.000
um we stuck with it and having paid the
00:13:38.560
time and cost by generating the tools,
00:13:40.880
generators and docs around setting up
00:13:43.040
new components, it's become part of our
00:13:45.519
everyday workflow. Now, for time, I'm
00:13:47.920
going to keep things at a high level,
00:13:49.040
but I want to talk about the differences
00:13:50.560
between these two and what's common
00:13:52.000
between them.
00:13:54.399
So, today if your app has grown to what
00:13:57.040
you call a monolith and you want to
00:13:58.880
check out pack uh you want to modularize
00:14:01.600
it, you should check out packwork. It's
00:14:04.399
called gradual modularization for a
00:14:06.880
reason. Um, I had to practice that a lot
00:14:10.000
saying modularization because that's a
00:14:12.000
really hard word to say. Um, now based
00:14:14.560
on this note on the Cobra website,
00:14:15.839
Hogerman itself would agree that yeah,
00:14:17.920
packwork is what you should probably
00:14:19.279
start with. Um, it just provides a lower
00:14:22.639
barrier of entry. So, I'm not here today
00:14:25.040
to try to convince you to use Cobra over
00:14:26.880
pack, but rather to show you the
00:14:28.320
differences along with some tools that
00:14:29.680
we've written to help manage things.
00:14:32.320
Now, at a high level,
00:14:34.639
packwork initially helps organize your
00:14:36.399
app folder into packs directories. Now,
00:14:39.040
at this stage, you're just moving files
00:14:40.720
around and your packs of related code
00:14:43.600
still rely on the gems and configuration
00:14:46.399
of your overall application.
00:14:49.279
Pack works tools help you identify and
00:14:52.320
deal with interaction between packs to
00:14:54.639
prevent circular dependencies and
00:14:56.399
isolate a pack code. And if you're just
00:14:58.880
organizing code, you can stop here. Many
00:15:01.279
who start, this is where they stop. They
00:15:03.199
don't ever make it get past this stage.
00:15:06.240
But if your goal is to eventually lift
00:15:09.600
your pack outside of your app into its
00:15:12.000
own app and repo, you need to take it to
00:15:14.720
the next step and make it a Rails
00:15:16.079
engine. It still is in the same place,
00:15:19.120
but it's now its own self-contained mini
00:15:21.120
Rails app with the configuration and
00:15:22.800
setup it needs in order to survive as a
00:15:24.959
Rails engine that lives outside of your
00:15:26.720
app.
00:15:29.519
And then once your pack is an engine and
00:15:32.079
your app's integrations with it are
00:15:33.600
ready, you can lift it out into a
00:15:35.199
completely separate app. Now that makes
00:15:37.040
it sound a lot easier than it really is,
00:15:38.720
but but the at a high level that's the
00:15:41.120
steps you have to go through. Um,
00:15:44.800
component-based Rails apps go straight
00:15:47.120
to a Rails engine. Both help you make
00:15:49.920
the transition from monolith to separate
00:15:51.600
repos easier because you can tackle
00:15:53.759
decoupling iteratively rather than all
00:15:56.399
at once.
00:15:58.800
The runway project I mentioned earlier
00:16:00.399
is an example of an app we extracted
00:16:02.560
outside of our nitro monolith. It used
00:16:05.279
to be a component but was lifted out and
00:16:07.360
now survives in its own repo and
00:16:09.519
application. So that's the first step in
00:16:11.360
making it open source. Now we just have
00:16:12.959
to u make it a generalized app that
00:16:16.480
anybody could use.
00:16:19.120
Now Cobra seems like a harder approach.
00:16:21.040
That's because it is. But recall we
00:16:23.440
started way before Packwork existed and
00:16:26.000
we really dedicated ourselves to the
00:16:27.839
journey. Now there's no magic wand. Um
00:16:31.680
you don't just start using it and fix
00:16:33.199
all your monolith problems. You have to
00:16:35.839
have a very strong commitment from the
00:16:37.920
business and your development team.
00:16:40.560
Packwork and Cobra require devs to
00:16:42.560
rewire your brains a bit from what
00:16:44.320
you're used to working with a normal
00:16:45.680
Rails app.
00:16:47.680
um you need to treat how code interacts
00:16:49.680
between packs or components similar to
00:16:51.440
how they would be as if they were
00:16:52.560
external services because if you're
00:16:54.480
going to lift them out it's going to be
00:16:55.920
an external service. So
00:16:59.600
decoupling components and libraries
00:17:02.079
requires a lot of time and that's why
00:17:04.079
you need the business support. Now, we
00:17:06.160
started this journey about eight or nine
00:17:07.679
years ago, and today all of our teams
00:17:09.839
are led by a lead developer who's
00:17:12.160
experienced enough to help guide new
00:17:13.919
team members so that we're always on our
00:17:16.160
path. We just made it part of our
00:17:18.480
culture. And as I said earlier, we put
00:17:20.160
our culture in code.
00:17:22.559
Now, you obviously begin with your first
00:17:24.400
component, and we chose this
00:17:26.640
intentionally long and nasty looking
00:17:29.039
name to boost our desire to get rid of
00:17:31.360
it.
00:17:32.880
Um, the benefits of doing just this
00:17:34.880
though is pretty underwhelming.
00:17:37.120
Everything being in one place really
00:17:38.880
wasn't impacting our 4-hour build times.
00:17:41.840
So, for a quick win, we decided to move
00:17:44.160
all of our models into their own
00:17:45.600
component to split up our codebase. And
00:17:48.080
by running two component tests in
00:17:49.760
parallel, we got a 50% buildtime
00:17:52.559
improvement. So, that was cheating, but
00:17:55.600
it gave us the confidence to keep moving
00:17:57.280
forward.
00:17:58.880
Now, this diagram logistically shows our
00:18:01.440
real starting point for flattening out
00:18:03.200
our initial gargantuan application. And
00:18:06.240
it didn't take long before things looked
00:18:07.840
more like this, which is part of what
00:18:10.080
Packworking uh Cobra helped manage the
00:18:12.799
complexity that you start to grow. Now,
00:18:15.120
this diagram is it's dense enough today
00:18:17.520
that it would not be discernible on the
00:18:19.520
screen. U so this was just an example of
00:18:23.039
something from a long time ago.
00:18:28.240
So something that makes it a lot easier
00:18:29.760
for us is a generator for bootstrapping
00:18:31.919
new components. Um existing libraries
00:18:34.799
that make it straightforward to jump
00:18:36.240
into development quickly and
00:18:38.160
documentation that walks developers
00:18:40.720
through what they need to know without
00:18:41.919
any friction.
00:18:44.320
Our build times today are about 90%
00:18:46.960
faster in some cases than at our worst
00:18:49.039
point. And surprisingly, it's getting
00:18:51.280
better even with a still growing code
00:18:53.760
base. Now, this is partly because we can
00:18:56.320
check a PR's code changes and determine
00:18:59.039
what components it affects and only
00:19:01.600
execute tests in those components. We've
00:19:04.720
also made tests more efficient. And a
00:19:06.400
huge shout out to Evil Martians. They're
00:19:07.840
getting a big shout out shout out at the
00:19:10.080
conference this year. Um, they helped us
00:19:12.240
reduce some build times with some of the
00:19:13.840
techniques and they use for uh for, you
00:19:15.919
know, test running and stuff. We're
00:19:18.720
still striving to shrink it further, but
00:19:20.480
uh but it's it's headed in a very good
00:19:23.200
direction.
00:19:25.200
Now, upgrading a monolith with that's
00:19:28.240
built on Cobra is obviously more
00:19:30.720
complicated, but it's primarily dealing
00:19:33.120
with merge conflicts and gyms that need
00:19:35.200
updating.
00:19:36.799
Updating gym files entails running
00:19:38.400
bundle update across all your
00:19:41.120
components. So, if you've got 160 of
00:19:43.679
them, that's a lot of bundle updates you
00:19:45.760
have to run. But, we do have a tool to
00:19:47.679
help manage that that I'll mention
00:19:48.799
shortly.
00:19:50.640
So this is a little list of some of the
00:19:52.240
stuff we get from Cobra over Packwork,
00:19:54.640
but when it comes down to it, we've
00:19:56.000
gotten faster build times and we've
00:19:58.160
finally realized the ability to extract
00:20:00.160
code out of our monolith. Both help our
00:20:02.640
developers ship faster and why power at
00:20:05.039
a business level continues its support.
00:20:08.480
So why not just use packwork installing
00:20:10.799
and quit calling a Cobra? We're
00:20:12.960
basically starting at step two of co of
00:20:14.880
pack work. So that's a good question.
00:20:17.200
it. We simply hasn't made it a priority
00:20:19.919
to investigate. But I am hoping to chat
00:20:22.160
with some of the packwork folks here at
00:20:24.000
Rubcom tomorrow to see if that's
00:20:26.160
something worth investigating.
00:20:28.799
After all, we do use packwork as a
00:20:30.880
double check to make sure we cover
00:20:32.080
undeclared and circular dependencies.
00:20:33.919
But this is just part of our build
00:20:35.200
process. Now,
00:20:37.760
now I mentioned that we have some tools
00:20:40.240
that help us be efficient. I want to
00:20:42.640
shift gears a bit to talk about some
00:20:44.000
open source projects we've created and
00:20:45.840
some of these are Cobra related but not
00:20:47.520
all of them.
00:20:49.440
So Cobra Commander
00:20:51.679
is a command line tool for Cobra
00:20:53.679
applications.
00:20:55.440
Um I used it earlier to show our
00:20:57.039
component count.
00:20:59.520
Um it can list component dependencies,
00:21:01.840
display a tree of them and orchestrate
00:21:04.080
commands to run within all components, a
00:21:06.400
single component or a component in its
00:21:08.080
dependencies. It's a great tool,
00:21:10.080
especially when updating your Ruby or
00:21:11.520
Rails versions. Um, for example, we can
00:21:13.679
use it to perform a B bundle update
00:21:15.600
across all of our components with a
00:21:17.280
single command. So, it makes it
00:21:19.039
incredibly useful when we're doing that.
00:21:22.320
And, um, you can I had to zoom in a lot,
00:21:25.200
but I I did like a graph of our
00:21:27.200
recruiting component, and I, like I
00:21:30.159
said, you couldn't it looked like a
00:21:32.080
smudge if you zoom out to see the whole
00:21:34.559
thing, but I tried to zoom in as best I
00:21:37.120
could.
00:21:40.000
So, Power Tools is actually a collection
00:21:42.159
of useful gems for all of our apps. Some
00:21:44.559
are Cobra, some are not, but there's a
00:21:47.200
lot of them. So, I encourage you to go
00:21:48.880
check it out if you want. Uh, I'm just
00:21:50.960
going to focus on a couple.
00:21:54.240
So, one issue that a monolith has is a
00:21:56.559
bloated schema file, and it's prone to
00:22:00.159
merge conflicts. Now, edge stitch breaks
00:22:03.760
up our schema by component into partial
00:22:06.080
schemas. Nitro has over 1,500 tables and
00:22:10.720
you can only imagine the amount of churn
00:22:12.559
having a single schema file would have.
00:22:14.799
I think I I'm pretty sure our developers
00:22:17.200
would revolt.
00:22:18.880
Um but we believe that a component that
00:22:21.120
owns a model should own its underlying
00:22:23.520
schema. So when performing database
00:22:26.159
operations, edge stitch stitches the
00:22:28.799
schema partials of a component and its
00:22:31.360
dependent components into exactly the
00:22:34.080
schema it needs. This helps with those
00:22:36.880
nasty merge conflicts quite a bit
00:22:38.799
because our schema is broken up across
00:22:40.559
components. And if you're curious why
00:22:42.559
this is SQL versus Ruby format, it's
00:22:45.280
because at one time you could update a
00:22:48.080
schema with information that Rails
00:22:49.760
couldn't replicate with schema.rb and we
00:22:52.080
just simply never changed, never updated
00:22:53.919
it. Uh we think it's schema RB can do it
00:22:56.799
now. So it's something we plan to do at
00:22:58.960
some point to convert it to use either
00:23:00.720
format.
00:23:02.880
Now, consent
00:23:05.039
is a gym that helps build a dynamic
00:23:07.200
authorization system that persists
00:23:09.520
permission assignments to the database.
00:23:11.520
It's built on top of can can. And I
00:23:14.559
guess we chose consent because that
00:23:16.080
sounded better than can can.
00:23:18.960
Um, but it makes it easy to set up
00:23:21.120
complicated permissions. It can be used
00:23:23.600
in any Rails application, not just
00:23:25.679
Packwork or Cobra. And this example, it
00:23:29.760
basically gives a new role permissions
00:23:31.200
to update projects that are only
00:23:32.720
associated within a user's department.
00:23:35.200
So how does that work?
00:23:38.320
This config basically says for a project
00:23:40.880
model, we can allow an update action
00:23:43.520
that can restrict a user to seeing
00:23:45.200
projects for their assigned department,
00:23:46.880
all projects or none in the UI. And
00:23:49.760
basically we store that in the database.
00:23:51.440
So when the uh uh application loads it
00:23:54.960
basically translates all this DSL stuff
00:23:57.440
into a can can can instructions so that
00:23:59.520
you can use it methods its methods
00:24:01.600
normally applying the appropriate filter
00:24:03.440
conditions. So makes it pretty slick to
00:24:06.159
easily add uh permissions and track
00:24:08.240
them.
00:24:10.320
And last but not least is our design
00:24:12.480
system playbook.
00:24:15.760
So, if you like some of the Nitro
00:24:17.840
screenshots I've shown, you can use this
00:24:20.159
same system in your applications.
00:24:22.880
Unlike almost every other UI system out
00:24:25.520
there for Rails, it's not based on
00:24:27.279
Tailwind CSS.
00:24:30.559
I I I see I have a lot of support. Um I
00:24:34.880
I literally looked this up the other
00:24:36.400
day. I'm like, there's literally no
00:24:38.159
other design system that doesn't use
00:24:39.840
Tailwind CSS. I'm like I just want to
00:24:42.159
stab my eyes out. Um, so to me that's a
00:24:46.000
big feature and it sounds like I've got
00:24:47.200
a lot of support. Um, so here's a simple
00:24:50.080
example for a Rails view. So Playbook
00:24:51.919
has allowed our developers to simply
00:24:53.440
drop in UX patterns without even
00:24:55.600
thinking about it. Plus you can use it
00:24:58.720
with React and Swift.
00:25:03.360
So there's a lot in there now, but we'd
00:25:05.440
love to expand it further with your
00:25:06.880
feature suggestions and contributions.
00:25:08.559
So we really encourage you to check it
00:25:10.240
out if you're interested.
00:25:14.080
And if you're curious to look through
00:25:15.279
more, you can check out all the power
00:25:17.840
home gems on Ruby gems. We've got a few
00:25:20.480
there. It's it's just coincidental that
00:25:22.720
I showcased some of the ones that I
00:25:24.320
talked about. I guess alphabetically it
00:25:26.880
was the first ones I encountered.
00:25:30.320
And we do have some open positions, by
00:25:33.279
the way. If you're interested, check us
00:25:35.279
out at our booth in the sponsors area.
00:25:37.120
And if you have questions, I'll hang out
00:25:39.039
here for a little bit. But uh otherwise
00:25:40.880
find me floating around the conference
00:25:42.559
or any one of my colleagues. We'll all
00:25:44.960
be wearing these shirts tomorrow. So we
00:25:47.039
will have a very big uh presence. So
00:25:51.360
look for us. And then thanks for all
00:25:54.159
your time and especially for the
00:25:55.520
RailsCom crew for all their great hard
00:25:57.360
work that they've done for us.