00:00:05.040
thank you
00:00:06.420
hi I'm Kevin
00:00:08.580
and I'm here to teach your code to
00:00:10.500
describe its own architecture
00:00:14.639
what do you think of this quote
00:00:16.500
documentation is the castor oil of
00:00:18.779
programming managers think it's good for
00:00:21.119
programmers and programmers hate it
00:00:24.300
well it's true that we prefer to code
00:00:26.160
that's why we're developers but what if
00:00:28.680
we can transform a documentation problem
00:00:30.720
into accounting problem
00:00:32.700
I'm a developer so when someone asks me
00:00:35.280
for documentation what I want to do is
00:00:37.980
build a program that makes documentation
00:00:40.800
making code that makes documentation
00:00:43.200
doesn't feel like drinking castor oil it
00:00:45.840
feels like making robots which is what
00:00:47.760
we all love to do right
00:00:51.480
a bit more about me you can think of me
00:00:54.180
as an inventor using software as a
00:00:56.579
medium
00:00:57.539
I started my career with C plus plus and
00:01:00.360
Java in 1995 building early interactive
00:01:04.019
web apps
00:01:05.760
I went on to start my first company in
00:01:07.920
2005 and joined the Ruby on Rails
00:01:10.560
community in 2008.
00:01:15.420
in 2012 I founded a devops cyber
00:01:18.240
security company called conjure which
00:01:20.820
was acquired by a larger company in
00:01:22.680
2017.
00:01:24.360
as we tried to integrate our cloud-first
00:01:26.340
rails app with their Windows data center
00:01:28.500
product we were really hampered by the
00:01:31.080
lack of good architecture and co-design
00:01:33.240
documentation
00:01:34.560
it was pretty disappointing and
00:01:36.540
confusing we have good documentation of
00:01:39.240
conjure it has a web service API server
00:01:42.479
configuration and setup High
00:01:44.640
availability and it was all documented
00:01:46.619
extensive test cases so why was there
00:01:49.259
still so much confusion among developers
00:01:51.479
about what it did and how it worked
00:01:55.979
I think it's because we write
00:01:58.079
documentation for a different audience
00:01:59.759
which is users
00:02:01.380
so even when we write good docs and even
00:02:03.840
when they're up to date
00:02:05.340
we don't help ourselves too much there's
00:02:08.039
a lot that we would like to be able to
00:02:09.420
learn and discover from docs and
00:02:11.220
diagrams but we can't because they were
00:02:13.440
written with someone else's needs in
00:02:15.180
mind
00:02:19.040
so who's making these architecture and
00:02:21.900
code design decisions well we are
00:02:24.780
in 2021 freedom to make decisions about
00:02:27.959
code design
00:02:29.459
belongs to developers architecture is
00:02:32.580
not something that's dictated by
00:02:33.959
Architects generally anymore
00:02:40.140
let's write this
00:02:41.879
here are some results from the survey
00:02:43.560
that we're conducting called the state
00:02:45.480
of software architecture quality one of
00:02:48.540
the questions we ask is who's primarily
00:02:50.819
responsible for enforcing software
00:02:52.860
architecture quality
00:02:55.019
and the answer is 68 of the time
00:02:57.420
Developers
00:02:59.040
and only 18 architects
00:03:05.400
so because we developers own the
00:03:08.160
decisions we also have responsibility to
00:03:11.280
communicate and explain those decisions
00:03:13.379
to other Developers
00:03:16.560
and what kind of Doc
00:03:18.540
do we need as we work we all play two
00:03:22.920
roles when we work in code that we wrote
00:03:25.019
ourselves we play the expert role we
00:03:28.140
know how it works
00:03:29.640
and we're the go-to source for questions
00:03:32.400
but when we work in code that we don't
00:03:34.140
know it's different we play a newcomer
00:03:36.659
role because it's unfamiliar
00:03:38.940
documentation serves users both internal
00:03:42.000
and external but usually not the people
00:03:44.220
who work on the code
00:03:45.900
we need a new kind of documentation
00:03:48.019
which experts create with code as they
00:03:51.420
work so that it's there when the
00:03:53.459
newcomers need it
00:03:55.379
foreign
00:03:57.739
we also asked would you like to have
00:04:00.900
up-to-date diagrams and visualizations
00:04:02.940
of code structure
00:04:04.920
and 84 said yes
00:04:07.920
then we asked do you use existing code
00:04:11.159
architecture and visualization tools and
00:04:14.220
would you like to keep using the tools
00:04:15.900
you're using in 81 said no
00:04:18.900
so the data shows that we want
00:04:21.120
up-to-date diagrams and visualizations
00:04:23.699
that are useful to us in our work and
00:04:26.400
there are tools that seem like they
00:04:27.720
might provide this
00:04:29.340
but they're not meeting our need
00:04:34.860
in a perfect world
00:04:36.600
what would we have available to us as we
00:04:39.120
work
00:04:39.840
dogs and diagrams that are up to date
00:04:42.300
they need to match the code exactly
00:04:45.900
they should be interactive so that we
00:04:48.000
can use docs like an app
00:04:50.100
static pictures don't scale
00:04:53.400
these docs would be contextual so that
00:04:56.520
we can get exactly what's relevant to
00:04:58.199
our task because even when information
00:05:00.300
is accurate it's not useful if there's
00:05:02.880
an overwhelming amount of it
00:05:05.400
and it should be as close to the code as
00:05:07.740
possible because the code is where we
00:05:09.540
work
00:05:10.440
and the code is our source of source of
00:05:12.479
Truth and we need to be able to move
00:05:14.220
seamlessly back and forth between the
00:05:16.680
code and our documentation app
00:05:19.320
so
00:05:20.940
with the remainder of this talk I'm
00:05:22.979
going to demonstrate a few tools that I
00:05:24.960
think can take us in the right direction
00:05:27.199
these are tools that automatically
00:05:29.520
generate documentation and
00:05:31.500
visualizations of architecture and code
00:05:33.539
design
00:05:34.979
the framework to keep in mind is model
00:05:37.259
view controller architecture because we
00:05:39.960
all know models views controllers and
00:05:42.479
how they work together
00:05:44.100
so I've chosen tools that auto document
00:05:46.740
the following things
00:05:48.479
first enter ad flows this is how we get
00:05:51.840
the right context for example figuring
00:05:54.539
out how a given web request uses
00:05:56.460
particular tables or finding important
00:05:59.100
functions performed by code such as
00:06:01.860
authentication authorization email
00:06:04.699
background jobs in a particular service
00:06:07.380
in essence the named actions performed
00:06:10.620
by the code
00:06:12.300
second web services these are the
00:06:15.000
commands that are set to the app
00:06:17.100
and third the data model
00:06:20.280
interacting with the data store is what
00:06:22.500
the app really does
00:06:24.060
from the standpoint of the user or the
00:06:26.220
business the operations that the code
00:06:28.620
performs on the data store are much more
00:06:30.900
important than the code itself
00:06:35.100
I'll start with that map which provides
00:06:37.500
both high level and low level views of
00:06:40.860
end-to-end code and data flows if you
00:06:43.440
want to follow along in the code or look
00:06:45.240
it up later I've created a fork of the
00:06:47.759
rail sample app 6th edition
00:06:50.039
within that fork is a branch called
00:06:52.080
eager lighting
00:06:55.680
so what's app map app map is an OSS
00:06:58.979
project that I created and I'm working
00:07:00.780
on actively
00:07:02.220
app maps help you navigate and improve
00:07:04.440
your code by showing you how it really
00:07:06.539
behaves feature by feature as you work
00:07:09.840
it does this by recording code Behavior
00:07:12.419
into Outlet files during program
00:07:14.400
execution
00:07:15.960
then you can visualize the app Maps or
00:07:18.240
analyze them using built-in analysis or
00:07:21.240
your own custom code
00:07:25.199
for Ruby you install that map as a gen
00:07:28.259
and configure which source files and
00:07:30.539
dependency gems you want to record
00:07:33.240
we record appmap files by running codes
00:07:35.580
such as test cases
00:07:37.199
this is different in static analysis
00:07:39.180
which only looks at your files on disk
00:07:41.639
appmap records your code while it's
00:07:44.160
running so it knows exactly what
00:07:46.259
happened at every point and how all the
00:07:48.720
code services and data stores fit
00:07:51.599
together
00:07:54.479
to create app maps you install and
00:07:56.759
configure the appmap gem
00:07:59.160
then run any code such as a test case
00:08:01.620
without map equals true
00:08:06.780
let's take a live tour using the rail
00:08:09.120
sample app
00:08:15.780
I'll start by logging in
00:08:28.879
the function of this app is to make
00:08:31.319
little Twitter style micro posts
00:08:39.659
foreign
00:08:45.300
Style
00:08:48.779
app
00:08:50.160
in the gem file
00:08:52.860
and I've configured the rail Source
00:08:55.080
directories
00:08:56.100
and some selected dependency gems in our
00:08:59.760
map.yml
00:09:03.660
now I can run any test
00:09:06.540
with
00:09:08.399
that map equals true to generate app
00:09:11.100
maps
00:09:13.620
I'll run a test an integration test
00:09:15.839
called users signup test
00:09:26.279
in this project
00:09:29.220
I have app maps of every mini test test
00:09:33.060
case
00:09:34.519
each app map is a data file that
00:09:37.320
contains a wealth of information about
00:09:39.779
what happened in the code while a test
00:09:41.580
case ran
00:09:42.839
if I open any app map I get a visual
00:09:45.720
depiction
00:09:47.640
of the code execution that's Interactive
00:10:05.399
opening any app map shows the dependency
00:10:07.560
map view this is your big picture view
00:10:10.080
you can see all the components that are
00:10:12.360
relevant to what you're working on and
00:10:13.980
how they're connected
00:10:15.600
it shows HTTP server requests
00:10:19.140
code
00:10:21.240
and SQL
00:10:23.339
you can search and navigate through web
00:10:26.640
services code libraries
00:10:34.860
and SQL
00:10:36.420
all in the context of a particular
00:10:38.459
feature
00:10:40.380
how it is depicted as packages which can
00:10:43.019
be packages in this project
00:10:45.060
or third-party gems
00:10:50.519
thank you and for many node you can
00:10:53.880
drill down
00:10:57.420
into the trace View
00:11:04.399
the trace view shows code execution in
00:11:07.440
detail as a tree
00:11:09.480
at the base of the tree our HTTP server
00:11:12.120
requests
00:11:13.800
the leaves of the tree are functions and
00:11:15.899
queries
00:11:23.100
each function call and query has full
00:11:25.440
details
00:11:26.760
parameter values
00:11:28.680
return values
00:11:31.980
exceptions
00:11:35.220
all recorded from program execution
00:11:38.700
you can click view source
00:11:43.560
on any cluster function to open the
00:11:46.019
source code in the IDE
00:11:49.620
functions are labeled
00:11:53.459
so that you can quickly find important
00:11:55.920
functionality such as authentication and
00:11:58.740
cookies
00:12:00.600
foreign
00:12:07.160
AP combines low level and high level
00:12:10.200
information
00:12:20.220
it links it all together and it shows
00:12:22.800
you how the code handles requests how
00:12:24.959
key functions such as authentication are
00:12:27.300
performed and how incoming requests
00:12:29.820
affect the database and external
00:12:32.160
services like S3 and other web and cloud
00:12:35.940
services
00:12:38.519
foreign
00:12:42.680
map provides the high level navigation
00:12:45.120
of the code interactively like a Google
00:12:47.760
map
00:12:48.600
you can write analysis code on the
00:12:51.180
outmap data which we'll see in a later
00:12:52.920
section and from maps you can dive into
00:12:55.560
source code debuggers
00:12:58.320
etc for further details
00:13:03.360
next up web services using swagger also
00:13:07.019
known as open API
00:13:10.500
there's a branch called Swagger within
00:13:12.959
the land of apps Fork of the rail
00:13:14.519
stampylap sixth edition same repo that I
00:13:17.700
used for that map
00:13:19.380
you can check out the branch for all the
00:13:21.540
code that I'm going to show in this
00:13:22.980
section
00:13:25.200
Swagger takes yaml or J Summit files
00:13:29.339
and generates a web page which is an
00:13:31.980
interactive catalog of your web services
00:13:34.980
the catalog contains routes methods
00:13:37.620
status codes parameters request body
00:13:40.940
authentication methods and more
00:13:43.740
the Swagger spec is extensive and
00:13:46.440
detailed swaggers oriented towards
00:13:49.139
documenting published apis because it's
00:13:51.899
pretty laborious to write and maintain
00:13:54.240
the files with auto documentation it can
00:13:57.300
be worthwhile to document internal apis
00:14:00.300
too
00:14:06.300
I think Swagger files is frankly
00:14:08.940
pretty tough
00:14:10.380
and there's a challenge of keeping it
00:14:12.120
accurate and up to date
00:14:14.040
so we can generate Swagger files so can
00:14:16.800
we generate Swagger files instead of
00:14:18.779
writing them I'm going to show two ways
00:14:21.180
of doing that starting with a gem called
00:14:23.100
R swag in our swag you write tests in a
00:14:26.639
dialect of our spec and it generates
00:14:29.100
Swagger Json or yaml
00:14:33.959
our swag is a gem and it provides a rate
00:14:36.360
task to generate the Swagger files from
00:14:39.300
the data you create in our spec
00:14:41.880
let's take a look at how it works
00:14:45.959
foreign
00:14:58.740
file
00:15:02.160
we'll find the r swag gem
00:15:06.420
it routes RB you'll find two R swag
00:15:09.240
engines UI and API
00:15:12.180
because our swag actually serves the
00:15:14.459
Swagger catalog directly from inside
00:15:16.920
your app this is very handy because it
00:15:19.500
means that the Swagger UI and your app
00:15:21.660
share the same session so you can swap
00:15:24.540
back and forth between the swaggered UI
00:15:26.760
under app interacting with both at the
00:15:29.459
same time
00:15:32.579
so I'll log into the UI
00:15:57.000
make a micro post
00:16:07.399
okay and then let's see the Swagger UI
00:16:19.279
you can see two functions here in in
00:16:22.800
Swagger the first one is a route to get
00:16:26.100
micro posts and
00:16:28.920
um this is a Json API style function
00:16:32.519
the second one is a function to create a
00:16:36.420
micro post
00:16:38.639
let's try this function
00:16:40.860
right here in the UI this is one of the
00:16:42.959
features of the Swagger catalog
00:16:46.920
so I can execute this this method and I
00:16:50.459
get back a Json list of my micro posts
00:16:53.639
and since I'm logged in
00:16:56.279
um and both of these tools are sharing
00:16:58.920
the same session I'm authenticated and I
00:17:01.380
can interact directly with my data
00:17:06.299
let's take a look at
00:17:09.360
where that came from
00:17:18.059
here's my R swag tests micro pose
00:17:21.360
controllers back so I'm not using
00:17:24.120
standard rspec I'm using these methods
00:17:26.459
like path get and response these
00:17:30.540
essentially mirror Swagger very closely
00:17:34.740
here's the Swagger pass route get
00:17:38.660
response very similar
00:17:42.059
so
00:17:43.559
if I want to add another route
00:17:47.720
Swagger I can add a new test
00:17:51.419
have to run that test if I want to
00:17:55.140
and then I run the rake
00:17:57.360
art swag specs Swagger eyes command
00:18:00.419
which will run over my my R swag and
00:18:04.799
update the swagger.yaml
00:18:07.860
so now you can see the log out route
00:18:10.140
here at the bottom
00:18:11.580
and if I go back to my
00:18:14.100
Swagger UI refresh
00:18:22.620
now I have the logout round
00:18:24.960
so if I do that
00:18:28.320
as you might expect
00:18:34.440
I logged out of I'm logged out of the
00:18:36.480
app
00:18:39.179
so from a developer standpoint
00:18:42.059
updated Swagger should be committed by
00:18:44.940
us when we make a web services change
00:18:47.400
similar to schema migrations or
00:18:49.880
structure.sql and then it can be diff
00:18:52.620
and reviewed in a pull request using
00:18:55.380
standard Source diff and other
00:18:57.600
procedures so this provides a powerful
00:18:59.940
way to track and review changes to
00:19:03.480
application web services
00:19:11.039
let's talk about some pluses and minuses
00:19:13.860
with our swag
00:19:15.360
on the plus side
00:19:17.340
the Swagger's Auto generated from test
00:19:19.440
cases so it's it's accurate
00:19:22.559
our swag also ensures that the Swagger
00:19:24.900
file is valid because it does assertion
00:19:27.780
checks when it actually runs the tests
00:19:30.000
you run you run those tests as our specs
00:19:32.760
and they are validated and that gives
00:19:35.400
you assurance that your Swagger is is
00:19:38.100
correct
00:19:39.419
and our swag is also very customizable
00:19:43.039
most if not all the features in open API
00:19:46.500
are also features of our swag so if you
00:19:49.559
know that format really well you can you
00:19:52.919
can
00:19:53.700
um
00:19:54.299
put a lot of detailed information into
00:19:56.280
your Swagger files
00:19:58.440
on the minus side you may have a lot of
00:20:00.720
specs already that aren't written using
00:20:03.059
our slag flavored R spec and to use our
00:20:07.020
swag you have to port or rewrite those
00:20:09.780
over in the r swag
00:20:12.299
flavor and you also need to learn a lot
00:20:15.480
about the open API format because
00:20:18.000
essentially the r swag format is the
00:20:20.580
open API format so you don't get a lot
00:20:23.640
of
00:20:24.480
um you don't get a lot for free there
00:20:26.220
you really have to know what what to put
00:20:28.679
in
00:20:32.760
so I'm also going to talk about another
00:20:34.980
option for Swagger which is called atmap
00:20:37.200
Swagger and this is brand new code that
00:20:39.600
I just wrote for this presentation so if
00:20:42.299
you go if you go try it and I hope you
00:20:44.280
do just remember that it's young code
00:20:46.620
and what it does is it generates Swagger
00:20:49.740
from appmap files which are pre-recorded
00:20:53.220
from test cases
00:20:55.500
so in order to generate Swagger without
00:20:57.960
map Swagger you install an npm package a
00:21:02.340
node package and then add an app map
00:21:05.100
Swagger rate test rake task and you can
00:21:08.100
see that you can see that in the sample
00:21:10.080
app for an example on the Swagger branch
00:21:13.260
and you can generate Swagger using rake
00:21:16.080
map Swagger
00:21:21.240
let's take a look at a demo of that
00:21:26.940
I've shut down the server
00:21:29.640
I'm going to go over to the
00:21:32.100
configuration
00:21:33.840
our swag UI
00:21:37.320
so I'm switching my
00:21:39.840
my source of
00:21:42.480
uh Swagger Authority if you will
00:21:46.559
from
00:21:49.320
this directory Swagger R spec over to
00:21:52.679
this directory swagger.map
00:21:55.380
and
00:21:57.320
let's try
00:21:59.820
great art map Swagger
00:22:04.200
so what this is going to do
00:22:06.059
is it's going to crawl over all these
00:22:09.299
app map files the same as what you saw
00:22:11.880
before and
00:22:14.400
each of these files contains data from a
00:22:17.640
particular test case including examples
00:22:19.620
of work of web service calls so I'm up
00:22:22.260
Swagger finds all the web service calls
00:22:24.360
that are in the app map files combines
00:22:26.760
it all together and converts that
00:22:28.440
information over into Swagger doc and it
00:22:33.179
looks like this
00:22:35.460
similar to what we saw from our swag
00:22:37.820
except more of it so
00:22:41.700
this was all completely discovered from
00:22:44.220
within my within my app maps
00:22:47.460
and if I go refresh the UI
00:22:53.159
I'll see this
00:22:55.799
very extensive list of
00:22:59.039
of routes
00:23:01.140
and all this came from test cases that I
00:23:03.419
already had because uh
00:23:06.059
the real sample out as you can see here
00:23:08.700
has
00:23:13.740
a good amount of tests
00:23:16.380
so uh map Swagger also makes it easy to
00:23:19.740
add a little bit of
00:23:22.080
parameter type information
00:23:24.659
so for example I can go in here and
00:23:27.299
these fields are already
00:23:29.220
created for me and I'll put in my
00:23:31.980
username
00:23:33.900
and the password
00:23:36.419
execute that
00:23:38.280
and then when I go over here to the app
00:23:40.679
I'm logged in
00:23:43.620
similar to what we saw with with our
00:23:46.080
swag
00:23:52.679
so pluses and minuses of map Swagger
00:23:57.179
on the plus side it uses your existing
00:24:00.059
test cases request functional controller
00:24:03.480
and integration tests anything that that
00:24:05.460
hits a controller or hits a web service
00:24:08.159
route will be will be discovered and
00:24:10.740
incorporated into Swagger
00:24:12.720
since it's generated it ensures it
00:24:15.179
ensures that the Swagger file is valid
00:24:18.320
and it matches whatever your code does
00:24:21.120
because it is literally made from your
00:24:23.760
code so it's accurate as far as the code
00:24:26.159
Behavior
00:24:27.720
um and you can get more complete API
00:24:29.760
coverage faster because it leverages the
00:24:31.919
test cases that you've got
00:24:34.140
you also don't need to learn very much
00:24:36.059
about the open API format
00:24:38.400
um I didn't have to I didn't actually
00:24:39.960
show you any open API there that was
00:24:43.200
handwritten by me there was a little bit
00:24:45.179
there to do the the login format but for
00:24:49.200
the most part you just get to use the
00:24:50.820
open API tools instead of having to
00:24:52.620
learn all the guts and how they work
00:24:54.120
which I like
00:24:56.100
on the minus side it's less customizable
00:24:59.039
than our swag or writing your own
00:25:00.659
Swagger because it's generated from
00:25:04.919
um using a code generator so there's
00:25:06.960
fewer options for configuration there
00:25:12.780
so in summary on Swagger you can see
00:25:15.360
your whole web services catalog and
00:25:18.179
interact actively with your API Swagger
00:25:21.960
also has some other functions like
00:25:23.280
generating client code
00:25:25.020
you can debug your web services in a
00:25:27.840
very granular way you can observe your
00:25:31.140
test coverage visually you can see
00:25:33.960
what's covered and what isn't reflected
00:25:36.059
back to you in Swagger
00:25:37.740
and you can diff your web services
00:25:40.260
changes by committing your Swagger
00:25:42.419
Gamble and then going through the
00:25:44.340
standard review process
00:25:53.940
final segment will be on entity
00:25:56.700
relationship diagrams
00:26:00.200
also a branch of the sample up sixth
00:26:03.539
edition Fork
00:26:06.539
relationship diagram if you don't know
00:26:09.720
shows the tables columns and relations
00:26:12.799
interrelational database schema and of
00:26:16.260
course we want to auto-generate the ERD
00:26:18.900
for a specific version of our code
00:26:20.880
directly from the database
00:26:23.100
so I'll show a gem called rails ERD that
00:26:25.860
does this
00:26:27.059
rail crd works by gathering database
00:26:30.240
metadata through activerecord it uses
00:26:33.059
active records so it's database
00:26:34.860
independent once it analyzes the schema
00:26:37.980
it generates a DOT file which can be
00:26:40.140
processed by graph this into a PDF
00:26:43.740
and all of this can be bundled up into a
00:26:45.900
rate task which
00:26:48.120
we can use to update the ERD when we
00:26:50.820
modify the schema
00:26:52.919
so in the project that I'll demonstrate
00:26:55.440
the ERD rate task is configured to run
00:26:58.380
automatically after dbmigrate so
00:27:01.080
whenever the schema changes the schema
00:27:03.480
diagram changes too
00:27:06.659
to use ERD you
00:27:09.360
um rails ERD install graphics and the
00:27:12.900
rails ERD Gem and then run rake DB
00:27:16.080
diagram
00:27:19.860
so let's take a look at it
00:27:23.820
here's my sample project
00:27:28.440
um
00:27:30.840
rails ERD installed here
00:27:33.840
so my middle exec rate
00:27:37.500
diagram
00:27:43.820
earning this rate task
00:27:46.440
Updates this file called entity
00:27:48.659
relations
00:27:50.340
dot PDF
00:27:53.400
and in that file
00:27:55.320
you can see
00:27:57.960
a detailed diagram of the schema this is
00:28:02.279
useful for analyzing the data model of
00:28:04.559
an app and identifying features such as
00:28:07.320
nullable and non-nullable columns column
00:28:10.260
types primary Keys foreign keys and the
00:28:14.400
different types of relationships
00:28:16.679
one to many many to one and many to many
00:28:20.820
one to one Etc
00:28:23.460
I can also get other insights from
00:28:25.679
looking at the schema
00:28:27.360
such as security I can see that the
00:28:30.179
password remember token and reset token
00:28:34.020
are all stored as a one-way digest so
00:28:37.140
that if an attacker obtained access to
00:28:40.020
this database they would not obtain
00:28:42.299
these secrets
00:28:47.159
so ERD you get complete details of your
00:28:50.760
database schema
00:28:52.980
foreign
00:28:58.940
the fully automated creation of three
00:29:02.279
types of code design dogs
00:29:04.140
at map covering end-to-end code and data
00:29:07.860
flows Swagger covering web services apis
00:29:11.059
and ERD describing the database schema
00:29:14.340
in detail and as I mentioned all this
00:29:17.159
code is available in our Fork of the
00:29:19.500
rail sample app so here are those URLs
00:29:22.080
again
00:29:25.799
there will be a dedicated q a session
00:29:28.320
for this talk in Discord
00:29:31.200
the channel name matches the name of the
00:29:33.720
talk
00:29:34.380
from 4 10 pm to 5 10 pm
00:29:38.039
eastern Daylight Time on Wednesday April
00:29:40.980
14th
00:29:42.179
thank you for your time and I hope that
00:29:44.100
I'll get to meet you in the Discord room