Episode Transcript
1
00:00:00,260 --> 00:00:02,650
-Hey. I'm Michael Dyrynda.
-And I'm Jake Bennett.
2
00:00:03,380 --> 00:00:08,780
And welcome to episode 182 of the North
Meet South Web podcast.
3
00:00:08,780 --> 00:00:11,460
-Chuka, chuka, chuka.
-Let's j-
4
00:00:11,460 --> 00:00:13,340
-Hey.
-Let's just assume you heard it. I don't
5
00:00:13,340 --> 00:00:15,630
know why you don't hear it anymore, but it
definitely played.
6
00:00:15,630 --> 00:00:19,440
I have no idea. It's, yeah, it's fine.
It's fine. Hey, everybody. Welcome to
7
00:00:19,440 --> 00:00:23,650
episode 182. We're going to skip the chit
chat. Do you know why? Do you wanna know
8
00:00:23,650 --> 00:00:27,600
why? I'll tell you why. I'm starting the
chit chat, but we're gonna skip it.
9
00:00:27,600 --> 00:00:30,420
-Do it.
-I am... Um,
10
00:00:31,500 --> 00:00:33,280
I think I'm entering that stage of life
11
00:00:34,040 --> 00:00:36,360
where you're just perpetually tired, all
the time.
12
00:00:36,360 --> 00:00:37,480
-Mm-hmm.
-I think it's just how it is. I think
13
00:00:37,480 --> 00:00:40,760
there's... I don't think there's any
coming back from it. I think it is just
14
00:00:40,760 --> 00:00:44,140
called life, and I think that's where I'm
at right now. And so I'm like, "You know
15
00:00:44,140 --> 00:00:45,800
what? Let's just get into it." Like,
16
00:00:46,460 --> 00:00:52,400
no need to, uh, you know, pretend like,
uh, we've got limitless energy here. Like,
17
00:00:52,400 --> 00:00:55,020
let's get down to the nuts and the bolts.
But
18
00:00:56,000 --> 00:00:57,520
that'd be missing one of my favorite parts
of the show-
19
00:00:57,520 --> 00:00:57,530
This has been two weeks in a row that this
has-
20
00:00:57,530 --> 00:01:00,210
... which is catching up with you,
Michael. How are things going, my friend?
21
00:01:00,210 --> 00:01:04,220
This is, this is two weeks in a row that
you've been, like, tired, tired. Which is
22
00:01:04,220 --> 00:01:08,950
-very unusual. So-
-Dude, it is. I think it... Well, I think
23
00:01:08,950 --> 00:01:10,220
-it's going back to the school thing.
-It could be something, like, it could be
24
00:01:10,220 --> 00:01:11,700
-seasonal.
-I think it's the changing of the weather.
25
00:01:11,700 --> 00:01:13,820
-Yeah.
-Yeah. I think that may be what it is.
26
00:01:13,820 --> 00:01:17,120
-Yeah, that's what it is.
-I am... We, we had like this pocket... So,
27
00:01:17,120 --> 00:01:21,300
we're heading into spring now, and, uh,
Australians, we just say like the first of
28
00:01:21,300 --> 00:01:25,090
September is spring. We don't, we don't
hang around for like the spring equinox or
29
00:01:25,090 --> 00:01:28,200
whatever the heck. You know, it's not the
22nd of September. We start all of our
30
00:01:28,200 --> 00:01:31,720
seasons on the 1st of the month. When
they- You know, on the q- on the quarter
31
00:01:31,720 --> 00:01:32,600
that they roll around in.
32
00:01:33,300 --> 00:01:37,500
-Respect. Respect.
-So we're heading into spring now, and, um,
33
00:01:37,500 --> 00:01:41,780
we... Because it's spring, it's like sun
but it's also rainy. But then it's cold,
34
00:01:41,780 --> 00:01:46,320
but then it's sunny, but it's not warm.
And so I had this pocket of time on the
35
00:01:46,320 --> 00:01:49,720
weekend where I was like, "I gotta mow the
lawn now 'cause the weeds are getting out
36
00:01:49,720 --> 00:01:51,760
of control." And
37
00:01:53,020 --> 00:01:57,540
I'm gonna do it so that when the lawn
stuff... Which I just shared a photo of
38
00:01:57,540 --> 00:02:00,1000
the, the box that this came in in, in the
cash money. From that-
39
00:02:01,000 --> 00:02:04,400
-Oh, okay then.
-It's a local company called Lawn Hub.
40
00:02:04,400 --> 00:02:05,860
-Mm, nice.
-Which sounds-
41
00:02:05,860 --> 00:02:08,660
-Good name
-... similar to another thing that is also
42
00:02:08,660 --> 00:02:10,919
-a hub, and their branding-
-Oh, sure. Yeah, GitHub.
43
00:02:10,919 --> 00:02:12,380
-Their branding-
-Yeah, sure. Yeah.
44
00:02:12,380 --> 00:02:17,020
Yes. Yes, definitely. Um, and their
branding matches color. Like, all of the
45
00:02:17,020 --> 00:02:18,769
-naming of stuff is-
-Oh my
46
00:02:18,769 --> 00:02:21,380
... is very much in line with the other
hub.
47
00:02:21,380 --> 00:02:24,900
-Mm, mm.
-And so, lawnhub.com.au. So I've, I've got
48
00:02:24,900 --> 00:02:25,320
their stuff
49
00:02:26,100 --> 00:02:30,780
had come in today, and so I had to mow the
lawn because you're not supposed to,
50
00:02:30,780 --> 00:02:35,079
like, spray... I've got this spray stuff.
You're not supposed to fertilize the lawn
51
00:02:35,080 --> 00:02:40,120
or do any of that kinda stuff within 48
hours, or 24 hours, whatever it is, of
52
00:02:40,120 --> 00:02:41,989
-mowing 'cause you wanna catch the weeds-
-Okay
53
00:02:41,989 --> 00:02:43,920
-... as they're in their growth cycle.
-Gotcha. Sure.
54
00:02:43,920 --> 00:02:47,280
So I did this on Saturday thinking I
better do it now 'cause it's gonna rain
55
00:02:48,180 --> 00:02:49,280
-on Sunday.
-Yep.
56
00:02:49,280 --> 00:02:53,260
And then it didn't rain on Sunday, and it
didn't rain on Monday, and it hasn't so
57
00:02:53,260 --> 00:02:56,320
far rained today but it's supposed to rain
this afternoon and all night today and
58
00:02:56,320 --> 00:03:01,730
-then tomorrow and Thursday. So I've got-
-Gotta put... Yep. You're playing the game.
59
00:03:01,730 --> 00:03:04,120
And, and it's like, okay, so I wanna do
60
00:03:04,120 --> 00:03:07,520
this, and you're supposed to do all of
this lawn care, you know,
61
00:03:08,320 --> 00:03:13,820
in September ahead of the growth period.
And it's like, I need to mow the lawn to
62
00:03:13,820 --> 00:03:18,070
get it ready so that the weeds are growing
to then hit it with not the, not the weed
63
00:03:18,070 --> 00:03:21,350
-killer but this is like a growth stuff.
-Okay, sure.
64
00:03:21,350 --> 00:03:25,880
That is supposed to, like... It's a
wetting agent and, and a fertilizer that's
65
00:03:25,880 --> 00:03:26,640
supposed to
66
00:03:27,420 --> 00:03:29,960
spring the lawn into growth. And of course
the weeds-
67
00:03:29,960 --> 00:03:31,400
-Okay
-... which are also there, and then as the
68
00:03:31,400 --> 00:03:36,340
weeds are growing on day 10, you then hit
it with the weed killer. Now, I don't
69
00:03:36,340 --> 00:03:37,250
-know-
-Interesting
70
00:03:37,250 --> 00:03:40,500
... I don't know how you're supposed to
plan this because how do I know in 10
71
00:03:40,500 --> 00:03:42,980
days, especially with the fits and starts
of spring-
72
00:03:42,980 --> 00:03:45,400
-Yeah, yeah
-... when the rain is gonna come? Because
73
00:03:45,400 --> 00:03:50,080
-you're not supposed to apply this stuff-
-Right before rain or anything like that,
74
00:03:50,080 --> 00:03:51,170
-yeah.
-Um, right before rain, you're not supposed
75
00:03:51,170 --> 00:03:51,840
-to, you know-
-You want it to be dry for a couple of
76
00:03:51,840 --> 00:03:53,640
-days, yeah.
-So I don't know.
77
00:03:53,640 --> 00:03:55,540
-It's tough, right? It's tough.
-So I'm just hoping it works out right.
78
00:03:56,620 --> 00:03:59,930
Yeah. We've got a buddy, I've got a buddy
who does like... He's really big into
79
00:03:59,930 --> 00:04:04,540
lawns and he's like, he goes out in the
spring and he measures his ground soil
80
00:04:04,540 --> 00:04:05,160
temperature.
81
00:04:05,780 --> 00:04:07,800
-Right.
-And so he'll like... If it's before, you
82
00:04:07,800 --> 00:04:12,240
know, if it's before the... You know, you
wanna get your pre-emergent weed control
83
00:04:12,240 --> 00:04:17,550
down between 58 and 61 or something like
that, and if you go, you know, I don't
84
00:04:17,550 --> 00:04:18,329
-know. So anyway-
-Not to that extreme
85
00:04:18,329 --> 00:04:20,899
... I just tell him like, "Hey dude, text
me when you're putting your stuff down."
86
00:04:20,899 --> 00:04:21,510
-That's what I always say.
-Yeah, and I'll do it.
87
00:04:21,510 --> 00:04:24,170
"Just text me when you're putting your
stuff down." And then I'll do it too.
88
00:04:24,170 --> 00:04:27,440
'Cause he lives you know, you know, five
miles away, so I'm like, all right.
89
00:04:27,440 --> 00:04:29,520
-Yeah.
-Chances are if it's, if his soil
90
00:04:29,520 --> 00:04:32,360
temperature is all right, it's, mine's
going to be about there too.
91
00:04:32,360 --> 00:04:35,280
-It'd be about the same, for sure.
-Yeah. Anyway, it's, that's a big help.
92
00:04:35,280 --> 00:04:37,630
-But, uh, anyway.
-So yeah. So, so doing that at the moment,
93
00:04:37,630 --> 00:04:40,130
but like trying to fit it in with, with
the weather is ridiculous.
94
00:04:40,130 --> 00:04:42,219
-Yep, yep.
-And so, because I mowed the lawn even
95
00:04:42,220 --> 00:04:45,900
though it was wet it was still enough to
kick up the pollen and so now hay fever
96
00:04:45,900 --> 00:04:47,810
-season is upon me.
-Oh, hay fever it is. Yep. Here it is.
97
00:04:47,810 --> 00:04:51,680
So, right. So this is my thing. You know,
I wake up in the morning, morning feeling
98
00:04:51,680 --> 00:04:54,580
terrible, not wanting to get out of bed
because my head hurts and my nose is
99
00:04:54,580 --> 00:04:59,440
congested and, and you know, we're back in
that. Fortunately, I know because I did
100
00:04:59,440 --> 00:05:00,020
mow the lawn
101
00:05:00,700 --> 00:05:04,140
and it is that time of year that I'm like
it is just hay fever.
102
00:05:04,140 --> 00:05:05,469
That's what it is, yeah. It's not
something else. Yeah. Yeah, yeah, yeah.
103
00:05:05,469 --> 00:05:08,860
I'm not playing the, the COVID or hay
fever game. So I feel rubbish in the
104
00:05:08,860 --> 00:05:10,230
-morning but Re-
-The COVID or hay fever game.
105
00:05:10,230 --> 00:05:10,840
... Re just
106
00:05:12,660 --> 00:05:12,930
had
107
00:05:13,620 --> 00:05:19,280
septoplasty because she's, like, she's
always had bad sleep. Like she will sleep
108
00:05:19,280 --> 00:05:22,060
-for 12 hours, wake up and still be tired.
-Mm-hmm.
109
00:05:22,060 --> 00:05:26,060
And so, you know, gets to a point where
you finally want to do something about
110
00:05:26,060 --> 00:05:28,160
this. You're not gonna just accept that
this is
111
00:05:28,800 --> 00:05:33,480
what it is. And so she went and saw an
ENT, an ear, nose and throat specialist
112
00:05:33,480 --> 00:05:38,100
and they said, "You know, you are waking
as you sleep
113
00:05:39,200 --> 00:05:40,560
but it's not enough
114
00:05:41,980 --> 00:05:46,720
that you need to start looking at a CPAP."
You know, face mask while you sleep kind
115
00:05:46,720 --> 00:05:47,180
of thing.
116
00:05:47,820 --> 00:05:49,960
-Yep, yep.
-This option of the septoplasty was to go
117
00:05:49,960 --> 00:05:54,100
in and to realign her turbinates because
she had a deviated septum in her nose.
118
00:05:54,100 --> 00:05:56,039
-Ah, okay.
-So they go in there and... Like day
119
00:05:56,040 --> 00:05:58,330
surgery, they go in there with a drill and
they go, you know?
120
00:05:58,330 --> 00:06:00,390
-Oh.
-Do whatever they do and sort it all out.
121
00:06:00,390 --> 00:06:01,700
Oh, nope, nope, nope, nope, nope, nope,
nope.
122
00:06:01,700 --> 00:06:05,180
So it was like day surgery but she was,
you know, she was under for it, of course.
123
00:06:05,180 --> 00:06:08,840
They don't do this while you're awake and
she woke up with-You know, like, no
124
00:06:08,840 --> 00:06:12,420
bruising. They they do it pretty pretty
good these days. Because, you know, we
125
00:06:12,420 --> 00:06:15,680
needed to start mucking around in there
around the place, it's like Oh, yeah. ...
126
00:06:15,680 --> 00:06:18,520
right near the surface. So you would
assume there'd be bruising and stuff, and
127
00:06:18,520 --> 00:06:23,080
I'd have questions to answer for a for a
few days after. Why has your wife got
128
00:06:23,080 --> 00:06:25,020
black eyes and all that kind of stuff.
But, um-
129
00:06:25,020 --> 00:06:26,820
Just stay home, honey. Just stay home.
I'll go do-
130
00:06:26,820 --> 00:06:28,070
-Yeah. So-
-... I'll go do other stuff that you need
131
00:06:28,070 --> 00:06:30,060
-to focus on something else.
-Yeah. So she was like ... She had a week
132
00:06:30,060 --> 00:06:34,280
off work which was which was nice, you
know, took care of the kids. And it was
133
00:06:34,280 --> 00:06:35,640
funny though because I said to her
134
00:06:36,340 --> 00:06:40,219
halfway through Saturday, like, she had
this surgery on on Thursday, and I said to
135
00:06:40,219 --> 00:06:44,020
her halfway through Saturday, I said,
"Look, I know that you had the kids for a
136
00:06:44,020 --> 00:06:50,980
whole week while I was in Denver. However,
you had the kids for a whole school
137
00:06:50,980 --> 00:06:54,219
week where you get them up in the morning,
you take them to school."
138
00:06:54,219 --> 00:06:56,820
-And then you say goodbye. Yes. Yes.
-And you say bye bye, and then you and then
139
00:06:56,820 --> 00:06:58,320
you see them again in the afternoon.
140
00:06:59,480 --> 00:07:00,880
Which, don't get me wrong-
141
00:07:01,539 --> 00:07:03,350
-You have them for a week
-... don't get me wrong, it's still ...
142
00:07:03,350 --> 00:07:05,269
Yeah. But don't get me wrong, it's still
143
00:07:06,000 --> 00:07:10,539
hard work. But there's seven hours out of
the day where they're not there.
144
00:07:10,539 --> 00:07:13,1000
-Agreed. Yeah. That's okay. Yeah.
-I had them Saturday. Right? I took them
145
00:07:14,000 --> 00:07:18,340
grocery shopping in the morning. We we got
home at lunchtime, and I'm like, crap. It
146
00:07:18,340 --> 00:07:22,240
is only lunchtime, and they're still
going. Like, they wanna keep going. I'm
147
00:07:22,240 --> 00:07:22,780
like, I
148
00:07:23,380 --> 00:07:27,580
I was so tired at the end of that weekend,
like, more tired than I've ever been.
149
00:07:27,580 --> 00:07:30,1000
-That's fine.
-But long, long winded way of saying, like,
150
00:07:31,000 --> 00:07:33,860
maybe you've got sleep problems, and this
is why you're feeling tired.
151
00:07:33,860 --> 00:07:37,930
Maybe. Maybe I do. Yeah. Or or maybe it's
just a seasonal thing too. I don't know.
152
00:07:37,930 --> 00:07:42,159
I'm not sure. That's a that is a fair
question. Um, I do see-
153
00:07:42,159 --> 00:07:45,680
Just don't be telling me it's still a
seasonal thing come December or come March
154
00:07:45,680 --> 00:07:47,010
-if you like.
-Yeah. Okay. Fair enough. Let's let's keep-
155
00:07:47,010 --> 00:07:48,330
You've gotta look into it.
156
00:07:48,330 --> 00:07:51,380
Let's keep checking in. Yeah. Let's keep
checking in on this. We'll see we'll see
157
00:07:51,380 --> 00:07:54,500
what's going on here, and I think that's a
this is a good you know, we'll we'll make
158
00:07:54,500 --> 00:07:56,820
this a recurring section of the of the
show here. So
159
00:07:57,539 --> 00:08:01,400
hey, with that out of the way, I am
actually really interested to hear about
160
00:08:01,400 --> 00:08:04,330
something you've been chatting about with
me recently,
161
00:08:05,060 --> 00:08:08,840
which is some of these fake HTTP stuff.
So, you know, we've talked about this on
162
00:08:08,840 --> 00:08:12,640
the show a number of times, this idea of,
like, this gateway pattern and how we
163
00:08:12,640 --> 00:08:19,080
structure it at Wilbur where, to give you
a quick rundown, we will create a gateway
164
00:08:19,080 --> 00:08:23,039
class which is responsible for newing up a
client, setting up the base URL, any
165
00:08:23,039 --> 00:08:26,200
tokens that would need to be retrieved or
pulled from the config to set up that
166
00:08:26,200 --> 00:08:30,740
client. And then we will have methods that
make calls to endpoints and handle any
167
00:08:30,740 --> 00:08:34,079
specifics around that endpoint, whether
it's caching or whether it's rate limiting
168
00:08:34,079 --> 00:08:37,669
or whether it's, you know, massaging a
response that we get back or have it
169
00:08:37,669 --> 00:08:40,840
handling an erroneous response and all
those things, which is great. But then
170
00:08:40,840 --> 00:08:46,579
what we'll do is we'll, uh, bind that into
in the container, um, and we'll bind that
171
00:08:46,579 --> 00:08:50,280
to, you know, an an interface. Right? And
that interface will be implemented not
172
00:08:50,280 --> 00:08:54,200
only on the HTTP side of things, but also
we'll have a fake that returns
173
00:08:54,819 --> 00:08:58,660
data that we have pulled probably from the
API, gotten a real response, and then
174
00:08:58,660 --> 00:09:03,460
we'll sort of load that into the fake. And
we'll have, um, different responses a la
175
00:09:03,460 --> 00:09:07,520
magic tokens. Right? So, you know, stripe
back in the day, you'd have 4242 gives you
176
00:09:07,520 --> 00:09:11,780
a valid response and 4141 gives you an
invalid CVV, whatever. So we do something
177
00:09:11,780 --> 00:09:16,200
similar to that. But I know that you guys
are big Saloon users, which if you don't
178
00:09:16,200 --> 00:09:19,200
know what that is, listener, uh, you
should definitely go check that out. Sam
179
00:09:19,200 --> 00:09:23,220
Carrey has an amazing package called
Saloon. Very popular nowadays. And I'm
180
00:09:23,220 --> 00:09:26,300
interested to hear kind of what you've
been kicking around with that. So you've
181
00:09:26,300 --> 00:09:30,079
been chatting about it a little bit, and I
wanna get a clear picture of what exactly
182
00:09:30,079 --> 00:09:31,040
it is you're talking about
183
00:09:31,740 --> 00:09:36,560
and if it solves some of the same problems
or or what you got. So go. It's all it's
184
00:09:36,560 --> 00:09:38,740
-all you, my friend.
-Yeah. So, yeah, I
185
00:09:39,340 --> 00:09:39,600
we
186
00:09:40,260 --> 00:09:45,020
we're doing this integration at the moment
where we had, like, some old, old library
187
00:09:45,940 --> 00:09:50,100
that was like, it's long since been
deprecated, no longer maintained. So we
188
00:09:50,100 --> 00:09:54,840
had copied the vendor code into our
application code to integrate with
189
00:09:54,840 --> 00:09:55,540
Salesforce.
190
00:09:56,440 --> 00:09:59,649
And that was, you know, to to push leads
in there, to pull contacts out, things
191
00:09:59,649 --> 00:10:02,880
-like that.
-So it's like a PHP Salesforce SDK sort of
192
00:10:02,880 --> 00:10:03,680
-idea?
-Yeah. Basically. Yeah.
193
00:10:03,680 --> 00:10:08,060
-Is that what it was? Okay. Okay. Sure.
-But it was you know, it was like PHP very,
194
00:10:08,060 --> 00:10:08,900
very PHP
195
00:10:09,500 --> 00:10:09,990
5 code.
196
00:10:10,660 --> 00:10:13,560
-Okay.
-But, yeah, long since unmaintained. And at
197
00:10:13,560 --> 00:10:17,400
some point in the last 18 months, I
think, like, fairly recently, we moved to
198
00:10:17,400 --> 00:10:21,140
using this other library called Forest, f
o r r e s t,
199
00:10:21,760 --> 00:10:27,260
and it allowed us to directly run SOQL, so
Salesforce object query language, I think
200
00:10:27,260 --> 00:10:27,919
-it is.
-Interesting.
201
00:10:27,920 --> 00:10:31,490
-Which is like the the version of SQL, uh-
-Okay
202
00:10:31,490 --> 00:10:34,860
... that you can use to query Salesforce.
And we thought
203
00:10:34,860 --> 00:10:37,920
-Customize the Salesforce. Yeah.
-This'd be a great solution. You know, we
204
00:10:37,920 --> 00:10:41,819
can write the queries ourselves. We can do
it. Um, but there was not really a good
205
00:10:41,819 --> 00:10:46,520
testing layer for it to the point where we
were using mockery and we were creating
206
00:10:46,520 --> 00:10:49,620
mock expectations that, you know, this
method would be called with these
207
00:10:49,620 --> 00:10:51,920
arguments. It would return this stuff. And
208
00:10:52,920 --> 00:10:56,940
the problem with that I mean, number 1,
don't test what you don't own kind of
209
00:10:56,940 --> 00:10:57,460
-thing.
-Oh, yep.
210
00:10:57,460 --> 00:11:03,260
But but number 2, mocks and I know that,
um, JMack has been on an adventure trying
211
00:11:03,260 --> 00:11:07,420
to improve this in, uh, I think, Laravel
specifically,
212
00:11:08,200 --> 00:11:10,740
um, and he's gone off and he's been doing
other things that have come up in the
213
00:11:10,740 --> 00:11:14,740
meantime. But he's been trying to improve
the messaging around when a mock
214
00:11:14,740 --> 00:11:18,780
expectation fails. Because when a mock
expectation fails, it just tells you,
215
00:11:18,780 --> 00:11:23,400
like, mockery underscore some, like, hash
or whatever that it's generated for this
216
00:11:23,400 --> 00:11:26,819
thing. It's saying, expected this, but it
didn't happen.
217
00:11:26,819 --> 00:11:27,960
-Yeah. Yeah. And it's very
-And that's it. Like-
218
00:11:27,960 --> 00:11:30,970
It's not it's not clear at all. The the
error message itself is is horrible. Yeah.
219
00:11:30,970 --> 00:11:31,700
It's horrible. It tells you that the
220
00:11:31,700 --> 00:11:34,860
expectation is not correct, but you don't
know why. And so then what you end up
221
00:11:34,860 --> 00:11:38,539
doing is, like, if you're a, quote
unquote, rule developer, you will go and
222
00:11:38,540 --> 00:11:41,358
fire up xdebug and you would follow
through and look at all these things. If
223
00:11:41,360 --> 00:11:44,380
you're a Laravel developer, you go and
start digging all over the place to see,
224
00:11:44,380 --> 00:11:47,670
like, what was actually in this object.
And and then you're looking, like, what is
225
00:11:47,670 --> 00:11:51,319
diff and whether you're using xdebug or
you're using DD, you still have to look
226
00:11:51,319 --> 00:11:54,920
at, like, what is my expectation and what
is in the thing. And some of these
227
00:11:55,680 --> 00:11:58,599
Salesforce objects are quite large. So
we've got 20 or 30
228
00:11:59,280 --> 00:12:01,980
things in here, and you've got to look at,
like, what's missing, what's added,
229
00:12:01,980 --> 00:12:04,920
what's different. Is it in a different
order? Is it somewhere else in the
230
00:12:04,920 --> 00:12:06,420
-response?
-Yeah. Right. Yeah.
231
00:12:06,420 --> 00:12:13,306
It's it's a whole thing. And so I was I
was poring through the... Saloon docs
232
00:12:13,306 --> 00:12:18,136
a while back for some stuff, and I saw in
there that someone had written
233
00:12:18,876 --> 00:12:20,396
a Salesforce
234
00:12:21,036 --> 00:12:25,456
SDK using Saloon. I thought, "Great. I'm
pulling that in immediately. I don't even
235
00:12:25,456 --> 00:12:28,116
have to read the doc, so I don't need to
know any more about it. It's written with
236
00:12:28,116 --> 00:12:29,796
-Saloon, it's gonna be good."
-Yep.
237
00:12:29,796 --> 00:12:31,315
And what that has
238
00:12:32,136 --> 00:12:38,616
enabled us to do, uh, obviously is to use
Saloon under the hood, which makes testing
239
00:12:38,616 --> 00:12:42,516
so much better because we can use Saloon
fake. We can say, "I'm expecting these
240
00:12:42,516 --> 00:12:45,936
res- requests to go out, I'm expecting
these responses to come back." We can do
241
00:12:45,936 --> 00:12:48,456
Saloon fakes, we can... Like, you know, we
can record fixtures-
242
00:12:48,456 --> 00:12:50,726
-So in the testing layer, you can, yeah-
-In the testing layer
243
00:12:50,726 --> 00:12:51,756
... record pictures and replay them back
out.
244
00:12:51,756 --> 00:12:52,476
-Fantastic.
-Mm-hmm. Yep.
245
00:12:52,476 --> 00:12:55,936
It has improved things a great deal to the
point where like, "Okay, we're gonna
246
00:12:55,936 --> 00:13:00,956
replace this Forest library with the
Saloon SDK." But as part of this, I've
247
00:13:00,956 --> 00:13:07,636
been doing some exploration, which is
like, I guess three-fold into, how do we,
248
00:13:07,636 --> 00:13:13,886
how do we do this kind of stuff with, um,
local development? Like, I don't-
249
00:13:13,886 --> 00:13:15,055
-Yeah, that's the question
-... want to be handing out-
250
00:13:15,056 --> 00:13:17,056
-That is the big question.
-I don't wanna be handing out keys to
251
00:13:17,056 --> 00:13:22,696
people to access Salesforce. Um, we, we
spin up and spin down Salesforce
252
00:13:23,396 --> 00:13:27,056
test environments as needed. Like, we
don't typically keep them around. So, you
253
00:13:27,056 --> 00:13:27,496
-might have-
-Sure
254
00:13:27,496 --> 00:13:31,276
... credentials to do something now, but
that, that environment might be gone at
255
00:13:31,276 --> 00:13:34,376
some point in the future when you come
back to it. Um, obviously we don't wanna
256
00:13:34,376 --> 00:13:38,296
test in production 'cause you end up
littering your Salesforce instance with
257
00:13:38,296 --> 00:13:43,396
all of these test accounts and things like
that. And so I, I started going down the
258
00:13:43,396 --> 00:13:49,076
path of, okay, what does this look like to
actually create a fake? And you and I
259
00:13:49,076 --> 00:13:53,396
have spoken about this, as you said
previously, where maybe you can just call
260
00:13:53,396 --> 00:13:57,136
Saloon fake inside a service provider
somewhere and record some fixtures and do
261
00:13:57,136 --> 00:14:01,996
all this kind of stuff. And so this, this
then led to my second point of ex-
262
00:14:01,996 --> 00:14:08,976
exploration, which was using AI. 'Cause
yeah, I'm a big AI boy now, and I like to
263
00:14:08,976 --> 00:14:10,556
I like to play with stuff. So I've been
using
264
00:14:11,276 --> 00:14:17,096
Claude and I've been, you know, with open
code, which is from the SST guys, um, Dax
265
00:14:17,096 --> 00:14:23,716
and, and Adam who are part of the, the
Terminal Coffee, uh, empire, um, have been
266
00:14:23,716 --> 00:14:27,096
building out this open code thing. Which
is kind of like, it's like Claude Code.
267
00:14:27,096 --> 00:14:31,646
It's a, a Terminal application, but it
allows you to hook into different
268
00:14:31,646 --> 00:14:35,236
providers and access different models
through those providers. So we use GitHub
269
00:14:35,236 --> 00:14:40,235
Copilot, um, which means we can't use
Claude as, as I understand it. Claude is
270
00:14:40,236 --> 00:14:45,696
to access the Anthropic, I think, the
OpenAI, whichever it is, their Claude
271
00:14:45,696 --> 00:14:48,006
-service using their Claude-
-Yeah
272
00:14:48,006 --> 00:14:51,265
... CLI. And then I think Cursor's got one
and, you know, all these other companies
273
00:14:51,265 --> 00:14:56,316
have got one. So what open code allows us
to do is to authenticate against GitHub,
274
00:14:57,196 --> 00:15:01,156
and then we have access to whatever models
we have access to inside of GitHub
275
00:15:01,156 --> 00:15:04,096
Copilot. So I can use Claude to then do
this stuff. So I've been in-
276
00:15:04,096 --> 00:15:06,236
-Interesting
-... planning mode. I spend like 45 minutes
277
00:15:06,856 --> 00:15:09,856
just going through, like, "I wanna do
this, I wanna do this." Like, blah, blah,
278
00:15:09,856 --> 00:15:13,476
blah. You know, come up with whatever we
wanna do. Switch to build mode and say,
279
00:15:13,476 --> 00:15:18,235
"Okay, now go build that." And so what
I've been doing, and it's been literally
280
00:15:18,236 --> 00:15:21,836
days 'cause I'm like feeling my way
through it. I'm not necessarily liking the
281
00:15:21,836 --> 00:15:26,356
output or it's, it's partially
implementing things. So, you know, which I
282
00:15:26,356 --> 00:15:30,276
think anyone that's been using AI for any
period of time knows that this is kind of
283
00:15:30,276 --> 00:15:34,016
the process. Treat it as a junior
developer that you're pairing with, and
284
00:15:34,016 --> 00:15:39,856
that's typically how you're gonna go. So
we have been building out a, a fake
285
00:15:39,896 --> 00:15:40,396
gateway,
286
00:15:41,076 --> 00:15:42,996
as you've done with Stripe, where
287
00:15:44,336 --> 00:15:49,376
in some instances, like if we wanna do a
search for a contact or an account,
288
00:15:49,376 --> 00:15:53,036
there's like, here are the, here are the
key phrases that you pass through. You
289
00:15:53,036 --> 00:15:56,856
know, search for Michael and you'll get
like three results back that are like
290
00:15:56,856 --> 00:15:59,075
-Michael A, Michael B, Michael C.
-Sure.
291
00:15:59,076 --> 00:16:03,756
If you search for Michael Dorinda, it will
return a single result, Michael Dorinda.
292
00:16:03,756 --> 00:16:08,796
Um, and so we've done this. Uh, I, I
reached out to Sam Curry, the author of
293
00:16:08,796 --> 00:16:12,176
Saloon, and I said, "What is the approach?
Like, how do we do this?" And he said,
294
00:16:12,176 --> 00:16:15,316
"You know, there's a few people that have
asked about this recently." And like a day
295
00:16:15,316 --> 00:16:20,016
after I'd asked about it, Alex Six from,
um, Zillow who spoke at Arc on US,
296
00:16:20,856 --> 00:16:22,636
um, he, he had pinged Sam
297
00:16:23,496 --> 00:16:25,056
on X and was like, "Hey,
298
00:16:25,936 --> 00:16:29,156
is this possible?" And so, you know, we
had this conversation about, yeah, we're
299
00:16:29,156 --> 00:16:32,816
exploring this at the moment. And what it
essentially boils down to
300
00:16:33,716 --> 00:16:36,915
is hooking into Saloon's global middleware
301
00:16:37,776 --> 00:16:42,476
and, and putting our own handler in there
that basically looks at, okay, is this
302
00:16:42,476 --> 00:16:46,396
enabled? Is our fake gateway enabled? So
with an environment variable and a conf-
303
00:16:46,396 --> 00:16:50,196
uh, environment variable and a config
switch, you know, if this is enabled-
304
00:16:50,196 --> 00:16:51,656
-Yeah, yeah
-... everything should go through our
305
00:16:51,656 --> 00:16:53,816
-Salesforce mock handler.
-Yeah.
306
00:16:53,816 --> 00:16:58,076
And then the, I've iterated on this a few
times where I've landed with like this
307
00:16:58,076 --> 00:17:02,856
registry patent approach where we just
register all of the, the response handlers
308
00:17:02,856 --> 00:17:07,896
we want. And each response class is then
responsible for providing its own should
309
00:17:07,896 --> 00:17:11,476
handle method. And it will look at the
pending request and say, "Okay, is this to
310
00:17:11,476 --> 00:17:15,356
an endpoint that I'm in of interest of?"
And so we've got 20 or 30 of these at the
311
00:17:15,356 --> 00:17:19,276
moment, and it would just like spin
through them all and go, "Okay, this is a
312
00:17:19,276 --> 00:17:24,735
post request to the contact standard
object endpoint. I'm gonna intercept that
313
00:17:24,735 --> 00:17:29,616
request and I'm gonna return this
response." And so we're then using Faker
314
00:17:30,816 --> 00:17:34,396
to just send back fake data. Um,
315
00:17:35,156 --> 00:17:38,836
and then where you can, you can seed Faker
316
00:17:39,576 --> 00:17:42,496
-with a, with a value, right?
-Okay.
317
00:17:42,496 --> 00:17:44,396
So that you get deterministic
318
00:17:45,116 --> 00:17:48,226
fake data back. So what we do is take all
of-
319
00:17:48,226 --> 00:17:50,156
-I never heard of this.
-Okay. So deterministic data
320
00:17:50,956 --> 00:17:56,556
is where like you are, it's pseudo-random.
Like it is random data, but it will
321
00:17:56,556 --> 00:18:02,116
always be the same random data based on
that seed. So you pass it a number from
322
00:18:02,116 --> 00:18:06,536
like one to whatever the upper limit is
that it supports, and then it will see the
323
00:18:06,536 --> 00:18:11,856
random number generator so that when you
call Faker whatever,
324
00:18:11,896 --> 00:18:16,728
it-Internally, it will process that. You
know, it'll go through its array of 50
325
00:18:16,728 --> 00:18:21,588
names, and if you've got a seed of 3, it
will always return the seventh value from
326
00:18:21,588 --> 00:18:23,888
that list of 50 names for first name.
327
00:18:24,708 --> 00:18:27,448
And then the next time you call it, it
will always return the same value and
328
00:18:27,448 --> 00:18:30,888
then... So then when you are developing
things, if you search for Michael, you're
329
00:18:30,888 --> 00:18:35,398
going to get the same Michael back every
single time on every single machine.
330
00:18:36,748 --> 00:18:37,238
-Because if you-
-Interesting
331
00:18:37,238 --> 00:18:40,888
... are searching for Michael and you get
a different fake value back, you know, in
332
00:18:40,888 --> 00:18:43,488
the UI context, it doesn't make sense, you
know?
333
00:18:43,488 --> 00:18:45,327
-Yeah. Yeah, yeah, yeah.
-But with deterministic seeding, it means,
334
00:18:45,327 --> 00:18:49,838
okay, here is, here is the value that I
want to base all of my random data on, and
335
00:18:49,838 --> 00:18:52,808
it will always do that. So what we do is
we look at the body of that pending
336
00:18:52,808 --> 00:18:54,468
request. We take all of the inputs,
337
00:18:55,168 --> 00:19:00,268
we join them together, and then PHP has
this function called CRC32, which will
338
00:19:00,268 --> 00:19:05,308
take a string and it will compute an
integer value that represents what that
339
00:19:05,308 --> 00:19:10,148
is. And then we pass that value into, um,
340
00:19:11,268 --> 00:19:13,008
into Faker's seed method
341
00:19:13,768 --> 00:19:16,668
so that we're always getting this data
back. And so-
342
00:19:16,668 --> 00:19:19,068
-Interesting
-... we've, we've now built out a fairly
343
00:19:19,068 --> 00:19:25,408
robust, um, implementation that will
always give us, like, pseudo-random data,
344
00:19:26,668 --> 00:19:29,768
but in a consistent way. So, like, if
we're searching for something, you know,
345
00:19:29,768 --> 00:19:33,488
we can, we can build our expectations on
it, we can build tests on it 'cause we
346
00:19:33,488 --> 00:19:36,868
know that, like, the fake data won't
change every time we run the test. We know
347
00:19:36,868 --> 00:19:40,158
that we're always gonna get the same set
of data back. So we can actually write
348
00:19:40,158 --> 00:19:44,788
tests against all of these endpoints with
the fake gateway enabled, knowing that
349
00:19:44,788 --> 00:19:47,828
we're gonna get back this specific data.
That then extends-
350
00:19:47,828 --> 00:19:49,818
-So when you say you seed it, you're not-
-Yes
351
00:19:49,818 --> 00:19:51,458
-... seeding a database.
-We're not seeding a database, no.
352
00:19:51,458 --> 00:19:53,458
'Cause they're not models in your
application.
353
00:19:53,458 --> 00:19:55,628
-No.
-You're seeding the responses that are
354
00:19:55,628 --> 00:19:58,208
gonna come back from your mock handler for
Salesforce.
355
00:19:58,208 --> 00:19:59,898
-Correct. Yeah.
-Yeah, yeah, yeah.
356
00:19:59,898 --> 00:20:01,888
-Uh-huh.
-So it's basically like with Faker, you're
357
00:20:01,888 --> 00:20:05,828
almost creating... I mean, it's not a
database, but it's almost a database
358
00:20:05,828 --> 00:20:08,648
because it's pseudo-random. I mean, it's
deterministic, right? So you're-
359
00:20:08,648 --> 00:20:09,768
-Mm-hmm.
-When I'm hearing you say, like, you're
360
00:20:09,768 --> 00:20:12,588
referencing, like, an ID, it's basically
like you're referencing an ID in a
361
00:20:12,588 --> 00:20:15,398
database that actually does not exist
because it's just seeded-
362
00:20:15,398 --> 00:20:18,088
-Correct. Yeah.
-You know, seeded fake data, essentially.
363
00:20:18,088 --> 00:20:18,908
-So-
-Wow. Yeah
364
00:20:18,908 --> 00:20:20,658
... you could think of it almost as a
365
00:20:21,708 --> 00:20:24,828
sort of database, I suppose. I mean, it's
not a database, but, like,
366
00:20:25,828 --> 00:20:28,668
same idea, right? Where it's
deterministic, you can write tests against
367
00:20:28,668 --> 00:20:30,088
-it 'cause it's not gonna change.
-Right.
368
00:20:30,088 --> 00:20:34,058
So it's almost seeded data, but you don't
have models backing this stuff.
369
00:20:34,058 --> 00:20:36,008
-Correct.
-So you have to use some other sort of
370
00:20:36,008 --> 00:20:37,047
-mechanism to do so.
-Yeah.
371
00:20:37,048 --> 00:20:38,968
-Okay.
-So you're, you're seeding the random
372
00:20:38,968 --> 00:20:41,688
number generator that PHP uses, which is
using, like-
373
00:20:41,688 --> 00:20:43,808
-Yep. Yep, yep
-... MT Rand or whatever under the hood.
374
00:20:43,808 --> 00:20:47,588
Yeah. MT... Like, it's a PHP function
under the hood. So if you always want to
375
00:20:47,588 --> 00:20:52,148
get the... This is quoting from the Faker
docs. "If you want to always get the same
376
00:20:52,148 --> 00:20:56,128
generated data, for instance, when using
Faker for unit testing purposes, the
377
00:20:56,128 --> 00:21:00,628
generator offers a seed method which seeds
the random number generator." And the
378
00:21:00,628 --> 00:21:04,908
crux of that is that calling the same
script twice with the same seed produces
379
00:21:04,908 --> 00:21:05,888
the same results.
380
00:21:06,548 --> 00:21:09,318
-Interesting. Okay.
-And this, and this-
381
00:21:09,318 --> 00:21:12,348
-Okay
-... is then why it becomes helpful in, in
382
00:21:12,348 --> 00:21:17,508
the... Like, in a, in a UI context where
if you are seeding based on the inputs, no
383
00:21:17,508 --> 00:21:20,028
matter what you put in there... Like, if
I put Jake in there
384
00:21:20,728 --> 00:21:25,528
or I put Michael in there or I put Eric in
there or I put Sam in there or whatever,
385
00:21:25,528 --> 00:21:29,268
as long as the inputs match, you will
always get the same results back, which
386
00:21:29,268 --> 00:21:33,107
makes the testing a bit more predictable.
If you hand that off to a QA team or, you
387
00:21:33,108 --> 00:21:38,108
know, for testing, or manual whatever, you
know that you, that it's... Like, it's
388
00:21:38,108 --> 00:21:41,768
not gonna make people stop and think,
"Wait, what happened there? 'Cause I got
389
00:21:41,768 --> 00:21:43,898
two different results back." It's like,
no, if I search for Jake-
390
00:21:43,898 --> 00:21:46,848
-Yeah, I guess, yeah
-... the same set of results come back.
391
00:21:46,848 --> 00:21:53,498
Right. So it's like you only... The only
benefit that you lose of fake data is that
392
00:21:53,498 --> 00:21:58,528
the randomness of it is sometimes a bit
of a fuzz test against, you know, can your
393
00:21:58,528 --> 00:22:02,028
code handle values that are not typical
sort of deal?
394
00:22:02,028 --> 00:22:02,648
-Yeah.
-Right?
395
00:22:02,648 --> 00:22:05,068
-Yeah.
-And so that, that's part of the idea of,
396
00:22:05,068 --> 00:22:07,948
like, Faker, which is like, "Hey, it
should be able to generate any value and
397
00:22:07,948 --> 00:22:11,308
it should always work." But it's like,
there are other considerations to be made
398
00:22:11,308 --> 00:22:14,208
too, and so you're just making a
trade-off. You're saying, "Well, we're
399
00:22:14,208 --> 00:22:17,768
okay with losing some of the benefit of
that randomness for the predictability of
400
00:22:17,768 --> 00:22:20,668
having deterministic values that are
getting seeded in here," and for all the
401
00:22:20,668 --> 00:22:22,428
other me- reasons you mentioned.
Interesting.
402
00:22:22,428 --> 00:22:23,988
-Yeah.
-I've never actually heard of this, so
403
00:22:23,988 --> 00:22:24,828
-I'll, I'll check into that.
-Yeah.
404
00:22:24,828 --> 00:22:28,408
-That sounds really cool.
-And so in, in the context of, like,
405
00:22:28,408 --> 00:22:33,008
actually opening up the application in the
browser and, like, using it, I think it
406
00:22:33,008 --> 00:22:33,278
-makes-
-Yeah, yeah
407
00:22:33,278 --> 00:22:35,908
... much more sense than having totally
random data.
408
00:22:35,908 --> 00:22:38,468
-Mm-hmm.
-Because if you think about it, if I'm, if
409
00:22:38,468 --> 00:22:41,448
I'm hitting Salesforce and searching for
Jake, well, I expect-
410
00:22:41,448 --> 00:22:42,868
-Yeah
-... Jake's data to always come back. I
411
00:22:42,868 --> 00:22:43,558
-wanna see-
-Absolutely, yeah
412
00:22:43,558 --> 00:22:47,128
... the same results. And so that's where
this comes in. And, like, this stuff has
413
00:22:47,128 --> 00:22:51,588
been in Faker, I don't know, since
forever. And the reason that, like, I'm,
414
00:22:51,588 --> 00:22:56,348
I, I know this fancy word, deterministic,
is 'cause I built this, um, avatar
415
00:22:56,348 --> 00:23:01,808
generator for Laracon AU, where I wanted
it to be random, but I wanted it to always
416
00:23:01,808 --> 00:23:06,158
be the same for a given input. So if I'm
gonna generate an image-
417
00:23:06,158 --> 00:23:08,688
Yeah, it's, it's almost like functional,
right? I mean, it's f- it's almost like
418
00:23:08,688 --> 00:23:11,168
functional programming where it's like
given the same inputs, you should expect
419
00:23:11,168 --> 00:23:13,328
-to get the same outputs every time. Yeah.
-Yeah. Yeah.
420
00:23:14,348 --> 00:23:18,468
Um, and so, yeah, that, that, that has
worked really well in that context and
421
00:23:18,468 --> 00:23:23,428
provides us, like, much more useful
output. I'm, I'm not sure... I still need
422
00:23:23,428 --> 00:23:27,708
to do a little bit of finagling to make
sure that I'm actually happy with
423
00:23:28,528 --> 00:23:30,428
-what has been built. Because-
-Yeah
424
00:23:30,428 --> 00:23:33,588
... largely it has been just, like,
driving the AI and letting it come up-
425
00:23:33,588 --> 00:23:35,148
-Yep, yep
-... with stuff and fixing things as they
426
00:23:35,148 --> 00:23:37,088
come. But it's, it's been pretty good in
terms of
427
00:23:38,128 --> 00:23:39,028
building the code,
428
00:23:39,668 --> 00:23:43,688
finding problems. Like, I've got it into
this loop now where we put into our Claude
429
00:23:43,688 --> 00:23:44,168
file,
430
00:23:44,948 --> 00:23:45,238
um,
431
00:23:45,948 --> 00:23:49,328
you know, make sure that you always run
PHP unit on the test. Make sure you always
432
00:23:49,328 --> 00:23:52,808
run CS Fixer. Make sure you always run
Stan, so if you've introduced any
433
00:23:52,808 --> 00:23:56,128
violations, like, it'll go back and fix
those things as well, which has been very
434
00:23:56,128 --> 00:24:01,938
helpful. Um, so I think the, the code is
robust. I think the, the... Then the third
435
00:24:01,938 --> 00:24:03,518
exploration is, okay, we've built
436
00:24:04,148 --> 00:24:09,108
this thing. Is this something that we
can... I don't know if we can package it
437
00:24:09,108 --> 00:24:13,388
up or if we produce a set of guidelines or
something that go, "Okay, now for the
438
00:24:13,388 --> 00:24:18,535
other things that we want it to
have..."... mock gateways for. You know,
439
00:24:18,535 --> 00:24:23,136
for a lender integration with a bank or
for a provider of, like, you know, Equifax
440
00:24:23,136 --> 00:24:26,156
or something like that where we're doing
these lookups. Well, we- we want the- the
441
00:24:26,156 --> 00:24:29,074
same data to always come back, but we
don't wanna hit Equifax 'cause that cost
442
00:24:29,076 --> 00:24:31,775
-money every time you do that.
-Again, and it will... And like you said,
443
00:24:31,775 --> 00:24:34,315
it's deterministic in a sense. You don't
have to spin up an Equifax-
444
00:24:34,315 --> 00:24:35,995
-Right
-... non-production environment sort of
445
00:24:35,995 --> 00:24:36,226
-deal.
-Correct.
446
00:24:36,226 --> 00:24:40,076
Like, it's like you just get all those
benefits that you're talking about. Now,
447
00:24:40,076 --> 00:24:44,916
there are, you know, there does end up
being some drawbacks, but, I mean, you
448
00:24:44,916 --> 00:24:47,515
know, there's drawbacks with the current
approach. So you just have to... It's the
449
00:24:47,515 --> 00:24:48,856
-trade-off, right?
-Yeah.
450
00:24:48,856 --> 00:24:51,896
-Um, you know.
-So in- in our tests, right, in our tests,
451
00:24:51,896 --> 00:24:57,555
we would still want to- to do this kind of
stuff with actual fake data. And that's
452
00:24:57,555 --> 00:25:00,795
where we'd dip into the Saloon fakes, and
we would use our fixtures and all of that
453
00:25:00,795 --> 00:25:03,745
kinda stuff. In terms of actually using it
454
00:25:05,015 --> 00:25:06,426
-by hand-
-Yeah, yeah
455
00:25:06,426 --> 00:25:10,916
... in the browser, yeah. Then, but- so
then the exploration was, okay, how do I
456
00:25:10,916 --> 00:25:11,436
build this
457
00:25:12,116 --> 00:25:12,856
infrastructure
458
00:25:13,596 --> 00:25:18,076
where I've got, like, a config file? Okay,
okay, here is Salesforce, but now here is
459
00:25:18,076 --> 00:25:23,315
Equifax, here is bank A, here is bank B,
here is lender A, all of these kinda
460
00:25:23,315 --> 00:25:27,255
things. And I just configure them in
there, and they'll register themselves,
461
00:25:28,035 --> 00:25:31,366
and then they'll find, you know, okay,
this is the thing that needs to hit this.
462
00:25:31,366 --> 00:25:35,216
And it all goes into Saloon's global
middleware and whatever needs to- to deal
463
00:25:35,216 --> 00:25:39,555
with any given request. And we can build
these over time. So I think I'm happy
464
00:25:39,555 --> 00:25:41,876
enough with it that I think that it will
work,
465
00:25:42,535 --> 00:25:45,876
and it seems to cover all of the scenarios
that exist currently
466
00:25:46,976 --> 00:25:51,775
until we start using it in practice and
figuring out, okay, how do we
467
00:25:53,275 --> 00:25:57,275
create the next gateway, the next mock,
the next mock, you know, and actually
468
00:25:57,275 --> 00:26:04,015
using it. That will be the determining
factor about if this approach is actually
469
00:26:04,015 --> 00:26:07,875
robust enough to be that flexible across
the board, so.
470
00:26:07,876 --> 00:26:10,856
-Yeah, yeah.
-We'll see. We- we might revisit that in a,
471
00:26:10,856 --> 00:26:14,836
in a few episodes and see if we've made
any progress on it.
472
00:26:14,836 --> 00:26:17,216
Yeah, it's like you're trying to look into
the crystal ball and determine what the
473
00:26:17,216 --> 00:26:19,616
-future's gonna hold, right? It's like-
-Yeah.
474
00:26:19,616 --> 00:26:24,054
It's- it's so funny, like, I... We talked
to... We talked to the dev team about
475
00:26:24,056 --> 00:26:26,395
this, and they're totally on board with
that- that approach where it's like
476
00:26:26,395 --> 00:26:29,896
sometimes you just gotta ship it and see.
You know what I mean? Like, just- just
477
00:26:29,896 --> 00:26:33,636
push the button and, like, you're not
gonna have the final answer. But, like,
478
00:26:33,636 --> 00:26:37,835
we're not building pianos here. Like, we
can go in and change the code. Like, it's
479
00:26:37,835 --> 00:26:40,916
not a big deal. You know what I mean? It's
like it doesn't have to be perfect the
480
00:26:40,916 --> 00:26:44,556
first time. It just has to be good enough
that it's not gonna break everything. And
481
00:26:44,556 --> 00:26:48,235
if it's good enough, then it's like you
can make modifications as you go, right?
482
00:26:48,235 --> 00:26:51,235
Um, but trying to make predictions about
how it's going to be used everywhere, it's
483
00:26:51,235 --> 00:26:55,676
just impossible. And I feel like my IT
team, they are on that train. They're
484
00:26:55,676 --> 00:26:58,275
like, "We have to have all the variables
solved before we push the button." It's
485
00:26:58,275 --> 00:26:59,335
-like, you don't.
-Mm-hmm.
486
00:26:59,335 --> 00:27:00,176
-You don't.
-Mm-hmm.
487
00:27:00,176 --> 00:27:04,255
You just need to have enough information
to make a good decision and then push it
488
00:27:04,255 --> 00:27:07,976
and see what happens and then learn and
move from there. But you can make
489
00:27:07,976 --> 00:27:11,696
decisions and make changes a lot faster
that way than you can hemming and hawing
490
00:27:11,696 --> 00:27:14,275
and waiting around and trying to get the
perfect answer. And it's like you won't
491
00:27:14,275 --> 00:27:17,515
have the perfect answer until you actually
start moving, then you're gonna figure it
492
00:27:17,515 --> 00:27:22,956
out. So, um, but the other part I was
gonna say is, like, this registration
493
00:27:22,956 --> 00:27:26,556
piece that you're talking about where,
like, you're registering all the different
494
00:27:26,556 --> 00:27:29,876
responses and things like that. And I'm
sure you'll find a way to organize this
495
00:27:29,876 --> 00:27:33,656
well, but, like, right now, two things.
Number 1, they're probably tied to actual
496
00:27:33,656 --> 00:27:39,815
-endpoints, I'm guessing.
-Yeah, so the... Each response has its own
497
00:27:39,815 --> 00:27:44,456
should-handle method, and it gets past
the- the pending request object. So it
498
00:27:44,515 --> 00:27:47,876
goes and looks like it... You c- 'cause
then you've got access to the request
499
00:27:47,876 --> 00:27:51,156
itself, and you can figure out, do I need
to intercept this or not? And
500
00:27:52,295 --> 00:27:56,815
depending on what it is, you know,
sometimes it's- it's enough to just look
501
00:27:56,815 --> 00:27:57,035
at
502
00:27:57,936 --> 00:28:03,176
the endpoint. Sometimes we wanna look at
the endpoint and the body and go...
503
00:28:03,176 --> 00:28:08,235
Because then we've got for authentication,
for example, we've got an email, like a
504
00:28:08,235 --> 00:28:12,255
specific email address for a successful
login. We've got a specific email address
505
00:28:12,255 --> 00:28:16,315
for a failed login, a specific email
address for, like, a- an account that
506
00:28:16,315 --> 00:28:20,876
doesn't exist, like all of these kind of
things. So some of it gets a bit grim. Um,
507
00:28:21,616 --> 00:28:23,436
some of these methods have got some
508
00:28:25,335 --> 00:28:28,626
creative regexes that Claude has written
in there.
509
00:28:28,626 --> 00:28:30,656
-Yeah.
-Which may or may not be the most
510
00:28:30,656 --> 00:28:31,975
-appropriate course of action.
-Yeah.
511
00:28:31,976 --> 00:28:36,056
But you... I mean, in- within the context
of each of those response classes, you can
512
00:28:36,056 --> 00:28:39,196
do whatever you want to determine if it
should be handled.
513
00:28:39,196 --> 00:28:41,436
Yeah. And so I guess that's what I'm
trying to figure out is, like, how do you
514
00:28:41,436 --> 00:28:44,735
co-locate the code that's going to be
handling or that's gonna be responsible
515
00:28:44,735 --> 00:28:48,176
for figuring all that out? And I'm sure
it's, like, you can have, like, some class
516
00:28:48,176 --> 00:28:52,295
double, you know, dot op generate or a
class dot op register handlers or
517
00:28:52,295 --> 00:28:54,356
something like that, where you can kind of
just say, like-
518
00:28:54,356 --> 00:28:56,076
-Right
-... for this particular type of response,
519
00:28:56,076 --> 00:29:00,476
we're gonna have a class named this that's
going to be, you know, by convention,
520
00:29:00,476 --> 00:29:03,876
it's gonna match the naming like this, but
it's gonna be called, you know, blah,
521
00:29:03,876 --> 00:29:05,896
blah, blah, response register handlers
class.
522
00:29:05,896 --> 00:29:07,795
-Yeah. Yeah.
-And then, you know, you just call that,
523
00:29:07,795 --> 00:29:09,576
-and there you go. And, and so you can-
-Yeah
524
00:29:09,576 --> 00:29:11,356
... break it up so it's not like some
massive
525
00:29:12,076 --> 00:29:16,116
just config file, essentially. You know,
there's actually some testability even
526
00:29:16,116 --> 00:29:20,446
around your- your registrations and things
like that, if you needed it to be as, uh,
527
00:29:20,446 --> 00:29:22,856
-as sophisticated as that. But-
-Yeah.
528
00:29:22,856 --> 00:29:25,535
-Maybe not.
-At- at the moment, this, like, registry
529
00:29:25,535 --> 00:29:28,396
that we have, it just, like, you
530
00:29:29,196 --> 00:29:35,556
pass it a, a namespaced path, like
app/gateway/sales floor-
531
00:29:35,556 --> 00:29:40,716
salesforce/fake/responses, right? And it
will go and look in there, and it will
532
00:29:40,716 --> 00:29:45,416
look through... Like, it just looks
through all of the files in there. And if,
533
00:29:45,416 --> 00:29:48,795
if it's a non-abstract class and it
implements an interface that we've got on
534
00:29:48,795 --> 00:29:49,896
there, it will then register it
535
00:29:51,136 --> 00:29:54,596
as a, as a handler. And then it will...
And then the
536
00:29:55,255 --> 00:29:57,476
Saloon is then responsible for passing all
of those
537
00:29:58,116 --> 00:30:02,755
things through and figuring out, should I
be intercepting this request? So it is-
538
00:30:02,755 --> 00:30:04,656
-Mm-hmm, mm-hmm
-... it has been done in such a way where,
539
00:30:04,656 --> 00:30:08,576
like, the registry will go and just, like,
discover all of these things
540
00:30:08,576 --> 00:30:12,616
automatically and then just slot them in
there. So definitely don't run it in
541
00:30:12,616 --> 00:30:14,085
-production.
-Right, right.
542
00:30:14,085 --> 00:30:18,255
Because you could be registering, like,
you know...... dozens to hundreds of
543
00:30:18,255 --> 00:30:22,255
classes for all of your Saloon
implementations. Um, but locally, like, it
544
00:30:22,255 --> 00:30:26,616
doesn't matter too much. Our machines are
so overpowered and over-provisioned that-
545
00:30:26,696 --> 00:30:26,985
Totally
546
00:30:26,985 --> 00:30:30,754
... having this do it. No, and especially
if you're just enabling them one by one.
547
00:30:30,755 --> 00:30:32,356
So there's, like, the top level
548
00:30:33,096 --> 00:30:35,856
is this thing that spins through the
config and then registers all the
549
00:30:35,856 --> 00:30:39,196
handlers, and then each handler is
responsible for then going and registering
550
00:30:39,196 --> 00:30:42,295
all of its responses. So if you've got
them all disabled, it'll just spin through
551
00:30:42,295 --> 00:30:45,716
that top level four or five or ten or
however many integrations you've got
552
00:30:45,716 --> 00:30:48,696
fairly quickly, and it'll just do nothing.
Like, we just filter them out of the
553
00:30:48,696 --> 00:30:49,176
collection.
554
00:30:49,936 --> 00:30:50,264
-So-
-Yes
555
00:30:50,264 --> 00:30:53,275
... I would like to share some code in
time once I've-
556
00:30:53,275 --> 00:30:55,616
-Yeah, absolutely
-... you know, happy that it is, it is
557
00:30:55,616 --> 00:30:59,775
actually a sensible approach. But, you
know, early indications, um,
558
00:31:00,876 --> 00:31:02,616
with, like, just the Salesforce
559
00:31:03,696 --> 00:31:09,376
mock, uh, seems to be good. The proof will
be in the pudding of whether or not it
560
00:31:09,376 --> 00:31:14,495
actually extends to other handlers. And
I've been trying to kind of guide the AI
561
00:31:14,495 --> 00:31:18,116
to make sure that this is extensible. And
anytime we start duplicating things, it's
562
00:31:18,116 --> 00:31:21,435
like, "Okay, let's pull this out, let's
hoist this up to the top-level namespace,
563
00:31:21,436 --> 00:31:25,726
let's, you know, make sure this is all
possible." 'Cause it is something that is,
564
00:31:25,726 --> 00:31:29,576
in my mind, that, like, we need to be
able to do this. So, I think the, the main
565
00:31:29,576 --> 00:31:32,976
thing is just... Salesforce is a very
566
00:31:34,696 --> 00:31:40,076
large thing. Like, there's a big surface
area of things that you can do. And so
567
00:31:40,076 --> 00:31:43,136
there's lots of overlap to the same
endpoints. But when you've got discrete
568
00:31:43,136 --> 00:31:47,936
endpoints, it's much easier to have, like,
a common thing that just, like, injects
569
00:31:47,936 --> 00:31:54,295
fake data based on the request kind of
thing, so. I, I, I feel good about it, but
570
00:31:54,295 --> 00:31:58,196
I'm still, um, cautious about
571
00:31:59,055 --> 00:32:02,416
how well that works as we start
integrating more. So we'll see how that
572
00:32:02,416 --> 00:32:06,035
-goes in time.
-That's exciting, dude. Yeah, I'm excited
573
00:32:06,035 --> 00:32:10,515
to hear about that. That's, um, that
sounds really cool. Uh, yeah, so we'll
574
00:32:10,515 --> 00:32:13,495
follow up on that in future shows. A
couple of things I wanted to share real
575
00:32:13,495 --> 00:32:19,456
quick before we wrap this one up. Bond is
a new thing by Filip
576
00:32:19,456 --> 00:32:25,085
Gagnik, Gagniks. I don't know how to say
his last name. Anyway, he's a Livewire and
577
00:32:25,085 --> 00:32:31,136
Alpine dude, and he just released this
library, Bond, uh, which is this
578
00:32:31,136 --> 00:32:32,255
interesting way
579
00:32:33,436 --> 00:32:33,975
to
580
00:32:34,616 --> 00:32:39,795
give you essentially, like, fully
reactive, optimistic UIs on the front end
581
00:32:39,795 --> 00:32:46,755
that are also Livewire-aware. So you get
the best of front-ends, like with
582
00:32:46,755 --> 00:32:50,015
modern JavaScript tooling, like being able
to do includes and things like that,
583
00:32:50,616 --> 00:32:52,876
um, and bundling and
584
00:32:53,775 --> 00:32:55,136
all those, all those pieces,
585
00:32:55,896 --> 00:33:01,436
and then also all the benefits of
Livewire. And so in his demo, that he put
586
00:33:01,436 --> 00:33:02,896
out a video today about this,
587
00:33:03,755 --> 00:33:08,156
um, he goes through and shows with this
counter component, it's fully reactive,
588
00:33:08,156 --> 00:33:11,815
and it's like he can plus, plus, plus,
plus, plus, plus, plus on this counter.
589
00:33:11,815 --> 00:33:14,896
And then in the bottom he has like,
"Here's what the Livewire server rendered
590
00:33:14,896 --> 00:33:16,525
-value is." And you can see-
-Hm
591
00:33:16,525 --> 00:33:19,315
... that on the front end he's able to
click it as fast as he wants and the front
592
00:33:19,315 --> 00:33:22,396
end stays reactive and it doesn't make
those back-end calls, and then it sort of,
593
00:33:22,396 --> 00:33:27,295
like, lazily updates that background,
that background, um, amount. And then when
594
00:33:27,295 --> 00:33:31,335
it makes a round trip, it ends up
updating that, that thing on the front end
595
00:33:31,335 --> 00:33:37,616
as well. Um, but your front end allows
you to continue to go just as fast as the
596
00:33:37,616 --> 00:33:39,235
browser front end will allow you to, as
long
597
00:33:39,235 --> 00:33:40,636
-Yeah
-... as long as the, you know, user's
598
00:33:40,636 --> 00:33:44,376
machine is able to catch up or, you know,
keep up with your JavaScript, uh, front
599
00:33:44,376 --> 00:33:48,775
end interactions. It will take care of
sort of eventually syncing in the back end
600
00:33:48,775 --> 00:33:50,495
-which is really, really cool.
-Mm-hmm.
601
00:33:50,495 --> 00:33:56,176
We've needed this in a couple projects,
and, um, he's got some, uh... It's just
602
00:33:56,176 --> 00:33:59,096
very interesting. It's got TypeScript
support, um,
603
00:34:00,315 --> 00:34:01,116
-super, super cool.
-Interesting.
604
00:34:01,116 --> 00:34:03,476
-So Vite basically will pull out-
-Do you wanna-
605
00:34:03,476 --> 00:34:05,755
-Go ahead.
-You'll have to send me a link so I can put
606
00:34:05,755 --> 00:34:06,616
-it in the show notes.
-Yeah.
607
00:34:06,616 --> 00:34:08,716
-It sounds interesting.
-Yeah, absolutely, I will. And I'll, I'll
608
00:34:08,716 --> 00:34:10,875
send you the, uh, the video that he made
here.
609
00:34:10,875 --> 00:34:12,235
-Mm-hmm.
-It's really, really good. Uh, Wilbur
610
00:34:12,235 --> 00:34:18,096
Powery, uh, talked about it, um, today in
our, in our dev chat. So there's the video
611
00:34:18,096 --> 00:34:22,976
and then I will send you the open source
repo as well. Both look really, really
612
00:34:22,976 --> 00:34:26,136
cool. It's a nine-minute video. You should
definitely check it out. Really well
613
00:34:26,136 --> 00:34:30,716
done. Uh, he seems like he, he essentially
manuscripted his video that he was gonna
614
00:34:30,716 --> 00:34:34,855
do. It's, it's nine minutes and it's just
pure code. Like-
615
00:34:34,855 --> 00:34:37,156
-Nice.
-... doesn't stumble over one word. It's so
616
00:34:37,156 --> 00:34:41,246
well rehearsed. It's the best video on a
new thing that I've seen people, you know,
617
00:34:41,246 --> 00:34:43,735
started to put out in a while. It's
really, really good. So
618
00:34:44,435 --> 00:34:49,815
shout out, Philip. Good job. Secondly, uh,
we've been talking about our journey, uh,
619
00:34:49,815 --> 00:34:53,995
at our company of restructuring a lot of
our roles and permissions and things like
620
00:34:53,996 --> 00:34:54,295
-that.
-Mm-hmm.
621
00:34:54,295 --> 00:34:59,336
And how we've sort of split the
responsibilities between, uh, basically
622
00:34:59,336 --> 00:35:02,656
saying our application's only
responsibility is to check permissions
623
00:35:02,656 --> 00:35:04,086
-with gate checks.
-Yes.
624
00:35:04,086 --> 00:35:10,935
And then what we've done is we have bound
those particular abilities to AD groups.
625
00:35:10,935 --> 00:35:15,016
And we've done that using... In AD, I mean
active directory. We've done that using,
626
00:35:15,016 --> 00:35:21,216
uh, enums and enum attributes, which I
swear is one of the most productive secret
627
00:35:21,216 --> 00:35:25,956
ninja combinations ever. Enums with
attributes is just-
628
00:35:25,956 --> 00:35:28,776
-Mm-hmm
-... awesome. It's so cool. Um, it allows
629
00:35:28,776 --> 00:35:33,796
you to have, like, type safety and also to
bind additional pieces of information
630
00:35:33,796 --> 00:35:37,856
directly next to enums, which I just
absolutely love. So really, really cool
631
00:35:37,856 --> 00:35:41,796
combination. I'm liking that. And I feel
like we've arrived at some conclusions,
632
00:35:41,796 --> 00:35:46,435
um, about how we've found to best
structure some of those things,
633
00:35:46,435 --> 00:35:50,375
specifically regarding, like, departments,
job titles, and stuff like that. So, um,
634
00:35:50,375 --> 00:35:53,496
I'm interested to share some of those
maybe in a couple weeks and-
635
00:35:53,496 --> 00:35:55,196
-Mm-hmm
-... talk about that and some of the
636
00:35:55,196 --> 00:35:58,856
discoveries we've made, and maybe talk
about this Bond thing too. We are-
637
00:35:58,856 --> 00:36:02,556
-Yeah
-... right now in the process of creating a
638
00:36:02,616 --> 00:36:07,875
two-way interactive texting experience
through SMS. So people who wanna get hold
639
00:36:07,875 --> 00:36:12,174
of our agents, they can do so through SMS.
We're using Twilio Conversations.
640
00:36:12,176 --> 00:36:16,424
But...... we're pulling a lot of the
Twilio Conversation stuff local. We're
641
00:36:16,424 --> 00:36:19,094
-saving records on our side.
-Mm-hmm.
642
00:36:19,094 --> 00:36:21,883
Um, Twilio's, like, the source of truth,
but we'll pull those down to our side, so
643
00:36:21,884 --> 00:36:25,364
we have database records then can- can
basically enrich that data with our own
644
00:36:25,364 --> 00:36:28,684
data. Um, and we're using a LiveWire front
end. We're building on a LiveWire front
645
00:36:28,684 --> 00:36:33,104
end, which is great, but this idea of,
like, the optimistic UI is very
646
00:36:33,104 --> 00:36:34,394
-attractive-
-Mm-hmm. Yeah
647
00:36:34,394 --> 00:36:36,804
... because sometimes it does, it can feel
a little bit laggy. You know what I mean?
648
00:36:36,804 --> 00:36:40,524
If you're doing, like, high volume
interactions back and forth, or you're
649
00:36:40,524 --> 00:36:43,104
trying to say, like, "Who's..." You know,
"Which one of our team members is
650
00:36:43,104 --> 00:36:46,644
currently in this conversation?" How are
we able to, you know, using presence
651
00:36:46,644 --> 00:36:48,844
channels or some of those things.
Sometimes it can feel a little bit laggy,
652
00:36:48,844 --> 00:36:51,564
or notifications if a new thing comes in.
You know, you have to kind of loop over-
653
00:36:51,564 --> 00:36:52,884
-Yeah
-... a bunch of stuff in the background.
654
00:36:52,884 --> 00:36:57,724
Anyway, um, I'm interested to see if this
is something we can start using and, um,
655
00:36:57,724 --> 00:37:00,604
since Wilbur Power is the lead on that
project, and he's the one who discovered
656
00:37:00,604 --> 00:37:03,454
this library, I'm interested to see if
this is something we might actually use in
657
00:37:03,454 --> 00:37:08,843
the next couple of weeks as well. So,
looking forward to that in the next show,
658
00:37:08,844 --> 00:37:12,484
-I suppose.
-Yeah. Yeah, so, um, Ash Allen, I think it
659
00:37:12,484 --> 00:37:17,004
was, tweeted something out about putting
methods on enums.
660
00:37:17,664 --> 00:37:20,604
-Okay. Yeah, yeah.
-Um, to, like, to- to return a label for
661
00:37:20,604 --> 00:37:24,124
something. Because, you know, your cases
and your names don't always match up with
662
00:37:24,124 --> 00:37:27,884
what or how you wanna present that to the
user, so he was talking about, you know,
663
00:37:27,884 --> 00:37:30,724
having a ToLabel method for things that
would then return
664
00:37:31,484 --> 00:37:34,704
something that you could just put into
your UI as opposed to what you're storing
665
00:37:34,704 --> 00:37:38,164
in the database. And then someone had put-
mentioned in there that, yeah, you can
666
00:37:38,164 --> 00:37:43,884
create attributes here that target, um,
like, the constants but, you know, enum
667
00:37:43,884 --> 00:37:48,604
members in that case, where you could put
like a pound square bracket label
668
00:37:48,604 --> 00:37:53,464
whatever, and then you've got labels
available through that as well. So, I
669
00:37:53,464 --> 00:37:57,684
think that's a, a, a, as you say, a really
powerful combination and it gives you a
670
00:37:57,684 --> 00:37:58,544
lot of flexibility
671
00:37:59,404 --> 00:38:02,984
across enums, not just... Like, I don't
have to create an, you know, a label
672
00:38:02,984 --> 00:38:06,924
method here or ToLabel and then a map and
then, you know, match the value to
673
00:38:06,924 --> 00:38:09,724
whatever. You can just put it straight
there on the, um,
674
00:38:11,064 --> 00:38:15,164
on the- the enum member itself, and then
you can do it on a case by case basis.
675
00:38:15,164 --> 00:38:18,244
Like, you would expose the label method
directly and would say, like, "Hey, is
676
00:38:18,244 --> 00:38:21,863
there an attribute here?" or return the
value of the attribute. Otherwise, you
677
00:38:21,863 --> 00:38:26,804
might do, like, a string snake or a string
title or whatever it is to, you know,
678
00:38:26,804 --> 00:38:30,964
have some fallback where you wanna do it
that way. So, yeah, I- I-
679
00:38:30,964 --> 00:38:34,824
-Yep. Yep. Really, really powerful combo.
-I do- I do think enums and attributes go
680
00:38:34,824 --> 00:38:38,944
-together like lamb and tuna fish.
-Yeah. Lamb and tuna fish. I've not heard
681
00:38:38,944 --> 00:38:44,464
that. That is a new one on me, and, uh, I
love it. I- I will add it to my list-
682
00:38:44,464 --> 00:38:46,004
-Pretty sure it was from Big Daddy
-... of things that I tell my friends.
683
00:38:47,224 --> 00:38:48,514
-I- I will tell my friends when-
-Big Daddy originals
684
00:38:48,514 --> 00:38:51,624
... when we talk about Australian
colloquialisms. So this is not a, this is
685
00:38:51,624 --> 00:38:53,933
not an Australian thing? Lamb and tuna
fish?
686
00:38:53,933 --> 00:38:54,204
-No.
-Oh.
687
00:38:54,204 --> 00:38:58,224
Lamb and tuna fish was a, it was a
character... Uh, it was Big Daddy. It was
688
00:38:58,224 --> 00:38:59,464
a character that, um,
689
00:39:01,444 --> 00:39:03,524
-uh, Rob Schneider played in that movie.
-Okay, okay.
690
00:39:03,524 --> 00:39:06,964
Where he was... Yeah, he was, he played,
like, you know, as Rob Schneider did back
691
00:39:06,964 --> 00:39:09,724
then, he played like a foreign, non-
nondescript-
692
00:39:09,724 --> 00:39:11,784
-Sure
-... foreign character. And he, yeah-
693
00:39:11,784 --> 00:39:13,684
-It's hilarious.
-I'll put a link in the show notes.
694
00:39:13,684 --> 00:39:17,664
All right, I'll have to check it out. Hey,
what episode are we on? 182?
695
00:39:17,664 --> 00:39:20,284
-That's right.
-182, folks. Thanks so much for hanging out
696
00:39:20,284 --> 00:39:24,604
with us. You can find show notes for this
episode at northmeetsouth.audio/182. Hit
697
00:39:24,604 --> 00:39:25,404
us up on
698
00:39:26,104 --> 00:39:30,343
X or on BlueSky at jacobbennett and
michaeldrinda, or at North Meets... Or,
699
00:39:30,344 --> 00:39:33,664
North South Audio. And of course, if you
liked the show we would really appreciate
700
00:39:33,664 --> 00:39:36,514
it if you'd rate it up in your podcatcher
of choice. Five stars would be incredible.
701
00:39:36,514 --> 00:39:40,514
Thanks, folks. Until next time, we will
see you. Bye-bye.
702
00:39:40,514 --> 00:39:42,584
Bye.