North Meets South Web Podcast

Join Michael and Jake as they dive into Laracon AU highlights, reveal new coffee adventures, and discuss dynamic directories and tenant file storage.

Creators & Guests

Host
Jake Bennett
Christ follower, software dev @wilbergroup using @laravelphp. Co-host of @northsouthaudio and @laravelnews with @michaeldyrynda
Host
Michael Dyrynda
Dad. @laravelphp Artisan. @LaraconAU organiser. Co-host of @northsouthaudio, @laravelnews, @ripplesfm. Opinions are mine.

What is North Meets South Web Podcast?

Jake Bennett and Michael Dyrynda conquer a 14.5 hour time difference to talk about life as web developers

Michael:

Hey. I'm Michael Duranda.

Jake:

And hi. I'm Jake Bennett.

Michael:

And this is episode 166 of the North Meet South web podcast.

Jake:

We've pink you still have the pink hair. I do.

Michael:

I still have it. The pink I forgot that it was set up. It's been that long since we recorded one of these podcasts.

Jake:

It has been a while. It has been a while. And so we've got a couple of things we're gonna cover today, folks. We're gonna continue on the tenant storage journey Mhmm. Talking about file systems and storing

Speaker 3:

file paths and directories

Jake:

in your database, and we're gonna referencing those things inside of your code with magic strings and enums and all sorts of fun stuff.

Michael:

And we're

Jake:

also going to talk about Laracon AU. Why don't we start with Laracon AU?

Michael:

Sure.

Jake:

How was it, my friend? Good. Awesome. I saw some people tweeting, like, today saying, you know, best conference I've ever been a part of. Like, it was absolutely incredible.

Jake:

All the good things. And so sounds like it was a huge hit.

Michael:

Yeah. It's it's fun that, 2 weeks on from the conference, people are still talking about it, and people are still posting about it. I've been saying LinkedIn, like, where I never get any traction for anything really. There's been quite a bit of, discussion and well wishes and and support of the conference there, which is which is really nice. I think, by and large, we kind of nailed all the aspects of of what we were trying to achieve this year, which I think is the most important thing that we I mean, as you know, we we put a lot of time and effort into putting networking as the center of of the event this year.

Michael:

Like last year, that was a kind of, a missing piece. And so a big focus in everything that that I did this year was to make sure that networking was front and center, that we made it possible for people to talk, to share, to engage with the speakers, to engage with sponsors, which is, you know, a first for us. We've we've always had sponsors at the events, but we've kind of been space constrained in a in a way that meant that people didn't really get a chance to speak with the sponsors. So I think that was that was possible with the the foyer that we had this year. We catered breakfast and lunch and afternoon tea this year, which made it possible for people to kind of stick around in the breaks and actually talk to each other without having to go and figure out where they were gonna go and get food and things like that.

Michael:

So that was good, and all of the feedback from the speakers talks was has been really good as well. We're going to or we will have, by the time this recording comes out, publish all the all the videos. So, yeah, looking looking forward to that, and, you know, everyone else getting an opportunity to see those videos. I mean, we did the live stream this year as well, which was something new

Jake:

for us. Right.

Michael:

We we hadn't previously like, we'd always recorded the videos, but we hadn't done a live stream. And and, you know, Taylor came to me a few months ago and asked, you know, are we gonna be able to live stream the the Nightwatch announcement? I said, well, I'll find out if we can do it. And then we didn't really wanna communicate it in any way because number 1, we hadn't done it. Number 2, the venue couldn't actually provide us a hard line to

Jake:

Oh, really? Okay.

Michael:

Do the streaming. They just they had no ethernet where the cameras were set up. So, but the the video team that we use, Bigspin, are very good at what they do. And they had, like, some bonded 4 g device. So they, you know, they had 2 different providers on there, and they were able to like, they were able to stream it at full 10:80.

Jake:

No Starlink?

Michael:

No Starlink. No. That's a that's an idea for the future. But, yeah. So that so we we didn't we we had always planned to specifically do the Laravel announcement.

Michael:

If nothing else, we wanted to stream that component of the conference, But we kind of left any announcement about that until we had gotten into the theater and were actually able to test the, you know, the throughput and thing. And, like, being able to test it the day before and being able to actually use it when there's, you know, 400 people in the room with their laptops and their phones and their iPads and whatever else is a is a very different proposition. But, yeah, we had a consistent stream across 2 days. So, yeah, Happy with that. The way that turned out.

Jake:

Yeah. That's that's awesome. Super cool. Did they give any indication why they call it Night Watch?

Michael:

I don't think so. I

Jake:

have to go back to the studio.

Michael:

Just another name.

Jake:

Just another name.

Michael:

Yeah. So, yeah. We just finished, putting together all, like, the thumbnails for the the videos. Because, you know, that's the thing we do. Video.

Michael:

Yeah. We got all the all the photos back from the photographer on the weekend. So I

Jake:

saw people posting them. Yeah. That looks great. Great. Really, really good.

Michael:

Been been going through those. You know, we we do that largely for the speakers so that, you know, they can put their portfolios and and, you know, if they submit to speak at other conferences or they we do headshots for them if they want, so they can update their LinkedIn and whatever other social media that they're using, or, you know, their website, whatever whatever they wanna use those for, we do that as well. So yeah. It was,

Speaker 3:

it was

Michael:

very cool then.

Jake:

Peak, speaker perk. Right? That's like a well thought through sort of thing because you're right. Like, everybody wants to be able to have those things, but unless it's done intentionally, sometimes it doesn't happen. Like, headshots for sure don't really happen.

Jake:

You know what I mean? Like, you get, like, the on stage speaker shot, but that's a great idea. The headshots, it's a good it's a good one. Yeah. Just as we keep

Michael:

taking you know, and, like, you you know,

Speaker 4:

as a conference speaker, you you put a

Michael:

ton of effort into it. Yeah. Right. You know, some conferences, I know, you know, ours does. I'm pretty sure Laracon US does.

Michael:

It'll cover accommodation and flights and and travel and things like that for the speakers, but many won't pay for you to actually speak necessarily. Like, most conferences won't pay speakers to present. You know, there's remuneration, as I said, in or reimbursement in terms of flights and accommodation and things like that. And so all these little extra things that that we can do, you know, there's the the speaker sponsor dinner. There's the the headshots.

Michael:

Like, we we do those as well for for the speakers just to, you know, make it seem like it's not a huge waste of I mean, not that it's a waste

Speaker 3:

of time, but, you know, it's a lot of time goes into it, and it's nice to be able to

Michael:

get something out on the other side of it as well. So

Jake:

Yeah. Absolutely. No. It's good planning on your part. I love that.

Jake:

It's, it's just, like, intentional. You know what I mean? And so, like, it's it just takes time to, like, think through that stuff and, like, put the planning in place to make that happen. So good on you. Good on you, mate.

Jake:

Thanks. Also, you got a coffee maker recently. A new coffee maker? Yes. Tell me about this adventure.

Michael:

Well, my old one, well, because I was away for a week. And I came back, and it was a bit bit weak in the in the steam wand department. Like, it was it was going, but it was not going very well. I'm like, oh, I better clean it out. You know, it's probably gotten to that time again.

Michael:

And I I went through the cleaning cycle, and like, it was okay. I'm like, this is on its last legs. And then there was, like, a early Christmas slash Black Friday slash whatever you want to sell at this place. And I was like, alright. I'll buy that.

Michael:

And so there's this this company makes, like, 10 or 12 different models of of coffee machine from, like, just a basic manual one all the way up to, like, fully automatic.

Jake:

Does your

Michael:

espresso, whatever. And so I got, like, the 3rd tier model, but it was on sale for less than the 2nd tier model was, which which was the one I was looking at. So I got that. And, yeah, I went to to make a coffee with my old machine yesterday and, like, the steam one just completely stopped. So I ended up with a a tepid coffee, which is not ideal.

Michael:

I'm like, no. I'm not drinking it. But fortunately, the new one arrived yesterday, so I got that out and just dialing it in at the moment. I don't know if, you know, people have bought espresso machines, but you've gotta mess with the setting. Basically, every time you get

Jake:

a new

Michael:

bag of beans, you've gotta go through and dial in to make

Jake:

sure the

Michael:

grind size is correct. You you supposed to.

Jake:

If you

Michael:

always buy the same beans, it's alright. But you never know when they were roasted relative to when when you got them, you know, how how much they were roasted and things like that. And the grind amount will impact the quality of the espresso and how much crema you get in there and things like that.

Jake:

So just

Michael:

just working my way through it. But I don't normally drink espresso. Like, I just have a a latte once a day and and and that's it. But I've been having I'm trying to keep myself to no more than 2, because just trying to get get it right. So but I'm pretty happy.

Michael:

It's kinda noisy though, but it's, it's I I was always about the life of, like, I'll grind the beans. I'll put them in the

Jake:

But it's so much time.

Michael:

The thing I mean, it's not a huge amount of time, but it was also part of my morning routine to do all of that. But I thought, no, this one this one does the espresso automatically. So I just push a button in it, you know, I can program it so that it's like, this is how I want my shot, you know, the temperature, the how much, you know, infusion there is and all that kind of stuff. And so Sure.

Jake:

Yeah. Yeah. Just put

Michael:

the thing in there and off it goes. But I do need to learn how to use the steam wand on this thing because it's, like, way more powerful even than, like, when it was working, but way more powerful than my old one. And it and it's on the left hand side. So and it only goes in one direction. And so it's a matter of figuring out, like, how do I hold this thing and and all of that with my wrong hand.

Michael:

So

Jake:

I'm looking to see what one we got. We bought well, not we. Our company bought 1. It starts with a j.

Michael:

A Jura. It's a fairly common one. Yeah. Yeah. J u r a.

Michael:

It's Yep.

Jake:

It's really nice. It's like a commercial version. You know what I mean? So it's like Yep. It's pretty sweet.

Michael:

Yeah. It's fairly it's fairly common in office environments. But, yeah, this one was this is a a gaggia a gaggia something. But apparently, this guy that you know, 80 years ago, he invented the espresso. Achilles Gaggia, his name was.

Michael:

It's an Italian Really?

Jake:

He invented the drink itself? And so this is his machine?

Michael:

Yeah. This is his machine.

Jake:

So That's pretty cool.

Michael:

Philips I think Philips, like, the electronics company Philips bought Yeah.

Speaker 3:

Yeah.

Michael:

Gaggia, like, in the early mid, like, the 2010s. Sure. And then try to, like, you know, move all the manufacturing and change the way that it was all done. And apparently, it was a bit of a disaster. And then in 2019, I went back to having everything manufactured in Italy again.

Michael:

And, yeah, it's been good ever since.

Jake:

And away you go. And now it's good again. Yeah.

Michael:

Good machine.

Jake:

That's pretty cool, dude. When I when I, head to your house in Aussieland, I'm gonna I'm gonna have to have, you'll have to have one waiting for me. Sounds good?

Michael:

Yeah. It's, it's the kind of like, you look at it and go, gee, they're expensive. But when you think how much coffee you drink, and, like, if I was to buy a cup of coffee, like, a a coffee every day, you know, we're talking 5, $6 a day. We're talking, you know, 300 let's say, 340 days of the year. It adds up.

Michael:

So

Jake:

Oh, absolutely. It does. Yep. Yeah. For sure.

Jake:

And so yeah. Like, it makes it a little bit easier to justify. Right? And so and it's so it's so much more convenient too. Like, you know, like I said, like, you know, it's part of your morning ritual, morning routine sort of deal, but, it's nice sometimes just to have, like, you push the button and it's done.

Jake:

It feels so nice. Here's my coffee. I'm good to go. So that's cool. Yeah.

Jake:

I've kinda actually so this is crazy. We have that Jira or whatever. Is it Jira? Yeah. Yeah.

Jake:

It's good. But, sometimes I still like Keurig. Like, I literally just got this, like, Keurig coffee. It's just like it's fine. Like, I don't need anything fancy.

Jake:

I just literally and, like, the Jura's being used by somebody else and, like, grab me a Keurig. I don't care.

Michael:

Yeah. I think also the thing with the, the office coffee machine is that you get, like, whatever subscription beans come with, like, the maintenance contract for the machine, and they're not necessarily gonna be fresh or

Jake:

So what I will tell you is this is this is the secret. Jordan Brill, who you know

Michael:

Uh-huh.

Jake:

His parents actually roast their own coffee. They have a company called Pyramid City Roasters.

Michael:

Sort of.

Jake:

And so we get fresh beans, like, you know, they are it is top notch. It is really good stuff actually. So That's,

Michael:

that's probably probably why that machine's busy all the time then.

Jake:

It is. That's exactly correct.

Michael:

Like, the beans, like, the way it's especially, like, if you buy a coffee machine and then you go and buy beans from the supermarket, and you look at the date on when those things were like, it it can be, like, weeks to months Oh, yeah. Before you

Jake:

get that.

Michael:

And, like, the beans beans, you generally wanna use within 2 weeks. So yeah.

Jake:

Jordan actually is messaging me right now. He, came over tonight while I was at a basketball game with my son, and he was like, hey. Can I borrow your belt sander? I'm like, yeah. Sure.

Jake:

So I opened up my garage door for him, and he went and grabbed the belt sander, and he's refinishing his, kitchen table or his, like, one of his tables. And so I thought the game was one of my one of our friends, one of our our, you know, our our mutual friends. And I I said, yeah. Jordan Sexton. He said, what's he doing?

Jake:

I was like, oh, he grabbed my belt sander. He's like, does that dude ever stop? I'm like, I don't think he does. Do not think he does. He just always has project going on.

Michael:

So good

Jake:

on him. It's looking good. He sent me some pictures.

Michael:

When I come to Laracon US next year Yes. That, he should bring me some of these Pyramid City coffee.

Jake:

Oh, yes. Oh, absolutely. He would love to. He'll listen to this. He'll bring him he'll probably send you some in Aussieland, man, for your new coffee machine.

Michael:

So expensive.

Jake:

No. You probably would. He's that he's that kinda guy. You know? He's just that kinda guy.

Michael:

I would appreciate it.

Jake:

Speaking of that kinda guy. Yes. Yeah. So Jordan and I are on a little venture here working on an application, which has been pretty cool, and some other developers on on our team. But, I think I can try and explain what it is.

Jake:

It's basically a data exchange. I wanna call it I mean, I'm using this, you know how Inertia is. So, like, Inertia is like a protocol. Right? It's not like a package library.

Jake:

It's like a protocol. It's basically what it is. Like, it it standardizes how you pass items from the Laravel back end to the JavaScript front end sort of thing, And it can use, you know, Laravel. It can use, Ruby. It can use whatever.

Jake:

Right? That's the idea. This is essentially like a data exchange protocol, I will call it, between insurance carriers and their subrogation vendors that they wanna use. So you have many insurance carriers, many subrogation vendors. Subrogation vendors is is what we do, by the way, Wilbur does.

Jake:

And so the process of getting data from an insurance carrier to your system of record is an absolute pain in the butt, and everybody does it 5 different ways. Right? So every single time you bring on a new carrier, it's a brand new integration path. It's like, someone wanna do SFTP, someone wanna do email, someone wanna do Excel sheets, someone wanna actually, you know, send them to a a, you know, your claim uploader on on the web or whatever. It's a mess.

Jake:

Everybody has a different way of doing it. Yep. The cool thing is that all of these carriers are going to this platform called Guidewire, which is a claims system that's like, you know, I mean, it's a piece of software, but they're they're creating a cloud version of it now. So they're pushing everybody to go to the cloud version. Well, we were approved as a partner, and we now have a Guidewire cloud accelerator that plugs in and then gives us access to their APIs.

Jake:

So what we do is we grab the data, we let them you know, they transport it to us, essentially. We standardize it, and we provide it in convenient formats to the subrogation vendor. So we have a UI, we have batches, and then we also have API. So it's like no code, low code, full code is the idea. Right?

Jake:

There's, like, all 3 paths available. So, like, a a vent a vendor could get started on day 1, or they could go, like, full integration mode and never touch it with a human. Right? Just go APIs. So that's the pitch for it.

Jake:

But some of this is we're dealing with a lot of file paths and a lot of directories. And one of the things we had talked about on the show previously was, like, tenant, file systems. How do we deal with that? Right? And so what we decided to do is each team has its own disk.

Jake:

So on the on the team record, there actually is a disk column. And so when we are pulling out anything for a team, we use storage disk and then tenant disk, and then we specify the team disk in there. And so that works pretty well. But we still have these file paths. Like, we have a relatively robust file structure system that we need to maintain in order to be able to allow them to have, like, s three access to these buckets, and it needs to be consistently named.

Jake:

So, like, they have, like, you know, vendor, uploads, downloads. Under uploads, you have, you know, claim updates, notes, documents, whatever. You have all these different file structures. And we were trying to figure out, like, I hate magic strings. Don't we all?

Jake:

Right? We hate magic strings in our in our code. And so I was trying to figure out, like, yeah, especially now. Now that we have enums, it's like enums to the rescue. Right?

Jake:

The only issue was that, our file paths had dynamic parts to them.

Michael:

Mhmm. Right?

Jake:

So you'd have a file path, but you'd have, like, an import ID would need to be a part of the file path or, like, a date would need to be a part of that file path. And so I'm like, man, this is super frustrating. How do I do this consistently between the classes and the tests and all that stuff? And then it hit me. I was like, we already do this in Laravel.

Jake:

Like, we use named routes. That's how we solve this problem when you're talking about, you know, going from web.php to, like, your tests to all that stuff. We use named routes.

Speaker 3:

Mhmm.

Jake:

And so, what we did is we used an enum called directories. We had directories, double colon, doodot, and then whatever you wanna name that named path. Right? So I would say something like directories, doodot, vendor, uploads, claim updates, like that. That would be like the enum.

Jake:

And, then what we can do is that thing, that enum, is equal to a string that looks exactly like what you would expect a named route to look like. Right? The path. So you have, like, vendor slash curly brace importidcurly brace/curly bracedatecurly brace/filing.csv or whatever it is. Right?

Jake:

And now what we can do is we can use those as placeholders. So import ID and date are now placeholders. And so what I did originally, although we did have some discussions about this today on our chat, what I did originally is I just sort of mocked what Laravel does with the route helper. Right? So you just call in Laravel, you call route and then you pass the named route as a string, typically.

Jake:

Although, now you can do it as an enum as well if you'd like to. And then as a second argument, you have any of the path parameters. Right? So you pass in an array and you'd say import ID, fat arrow, you know, 1 comma date equals now format ymd. Whatever.

Jake:

Mhmm. And that's it. And it and it and it pops it out. Right? So instead of using route though, we use a helper called directory.

Jake:

So directory, you pass in the enum, then you pass in the array of those values. And then as an optional last argument, you can also pass in a file name. So the reason we have to do this is because sometimes you only need the directory location, and sometimes I actually need the full file path of a file name in that in that directory.

Michael:

Yeah.

Jake:

And so the file name as a last argument is optional, but if you pass it in, it'll put a final directory separator and then the file name dot, you know, whatever it is. Mhmm. So this has been incredibly helpful because in all the places where we were previously using just these, like, glued together strings, and I had absolutely zero confidence that our tests were actually doing what they were supposed to be doing, like they were actually testing the correct location. Now I have a lot of confidence that they are hitting the right locations because I can use the enum, to ensure that that's the case. And then if I ever need to change them, I command command click on that enum case, and any of the places where it needs to change, I can go look at.

Jake:

So Mhmm. Oh my gosh. So incredibly helpful. And so that's a great Yeah.

Michael:

It's not like it gives you that consistency, especially, like, when you're dealing with situations where you need to retrieve those things later. And what you would previously have done is, you know, do the thing here in, like you save it over here. And then later, you need to then go and fetch it. So you need to go and look at the place where you've saved it to make sure that you load the same thing back out, you know, figure out all the parts and prefixes and and variables and things like that. So putting it into an AM is good.

Michael:

So it's good from the consistency perspective there. The one thing that you would probably wanna consider, whether or not it's a it's a real thing, is, like, if you ever need to change the paths. Right. Like, everything that's already saved, you need to handle the situation. Like, do you go and move all of those?

Michael:

Do you do, like, a migration of the, you know, from the old path to the new path? Do you decide, like, no, we can never do this? Or do you, like, handle, you know, we create a new, you know, e num member and, like, this is how we do it moving forward if we ever wanna change it.

Jake:

It's a really good question. And I actually was just looking this up. Because you're you're hitting on sort of a second thing. So the first thing I was concerned about was how do I make sure that I'm consistently generating these paths in my code? And that problem, I feel like, is solved.

Jake:

The second problem, though, is how do I store these in my database? Right? What is the correct method to store these in my database so that I can later retrieve them? Right? Because, unless I'm storing all of the pieces that I used to create that string, I will not be able to recreate that string later Yeah.

Jake:

Using that same method. So there's a couple options. Right? I can actually store the entire file path in the database record, but that makes it difficult, like you said, to to move things. Yeah.

Jake:

So I've actually I I kinda looked up a couple different options for how people do this. Mhmm. Let me see. Let me make sure that I've I'm presenting the whole problem before I before I jump into the solution, though. So yeah.

Jake:

Like, you

Michael:

Where you're at is

Jake:

You're the where Go ahead.

Michael:

Where I think most people normally land is that you would store the path to whatever that file is in the database. And then if you're using whether your own implementation or something like Sparsity Media Library, where you attach these things then to a model, at least you've always got reference back to the thing that it was related to. But, yeah, if you if you wanna move around, you you know, you need those variables back out. You need to know how to get back there, which is which is a thing. So I think you would probably not want to ever ever change those things once they're set.

Michael:

And that way, you don't ever have to worry about going back to this directories helper, because you would only ever pull it out of storage using the path reference and the disk. So, you know, you do storage disk Yeah. Dollar team, disk or whatever whatever it is, arrow, and then whatever the path is from from that record. If you're wanting to be able to move things where you would have to, like, pull down that file and then, you know, get whatever the directory is at that time and then update the path, you could probably do some, like, date based things and put a match statement in there. That's like, if the thing was before this date, like, go and get this value otherwise.

Michael:

Like, you could there there are certainly ways of doing it. But I think the only time it's really gonna be problematic is if you need to move existing files.

Jake:

The good news for me is that and and agree. I agree. It's like you don't know what you don't know. So it's like you wanna maintain as much flexibility as you can. Yeah.

Jake:

I I would say the good thing for me though is that most of these files are not super long lived. Like, they're not insanely relevant after about a week. So it's not like I'm gonna have months years worth of data that need to get moved if I do change file paths. I could probably just say, like, the life of these is 30 days max. And if you haven't gotten it by the time 30 days is around, I'm not storing them for you anymore.

Jake:

Yeah. So Are you using

Michael:

s 3? Because you you said like, you set up your expiration rules, and that would just disappear automatically. So you don't have

Jake:

to worry about it. Yeah. That's a great call actually. Yeah. I've done that before.

Michael:

Life cycle rules. You set them up on the because if you don't need to worry about it, you can set up the life cycle rules, which would make sure it's deleted. And then you'd probably schedule some task to, you know, model prune and and delete the the data from your database. You're not keeping that as well, if if that's where you were going.

Jake:

Yeah. No. That's that's interesting. The life cycle hooks thing, I hadn't thought about that. Yeah.

Jake:

I mean, that actually is something really interesting that I've tried a couple times, is those life cycle hooks in s 3 or those life cycle rules. I actually had it bite me the other day because we've been using airdrop to to push items up to s 3 and then pull them down in production. And I went to redeploy an existing deployment in, in one of our sites. And it was like, okay. Great.

Jake:

No problem. I'll just pull down that airdrop thing and Not there anymore. It's not there anymore.

Michael:

You're gonna

Speaker 3:

be careful

Michael:

with the with the left yeah. You're gonna be careful with the life cycle rules.

Jake:

Yeah. Yeah. And so I just extended the life cycle rule. It was, like, 30 days, and then I extended it to a year. Like, it doesn't matter.

Jake:

It's a year. It's not a big deal. It's not there's not that much stuff in there. So Mhmm. So anyway so here's what I would say though.

Jake:

The the the trick for me, which makes it a little bit complicated, is I have one area of the code and the storage in which is under my complete control. So, like, I'm totally aware of what it is, and nobody really can modify or mess with the structure of it. So one way you could do that is if you just, for the record, which you're creating a uploaded file for, you just have, like, a UUID or a UUID, and you just name that file that. No extension. Just you literally name it that.

Jake:

And, then inside of the database record itself, you would save, like, the original uploaded name with the extension.

Michael:

Yeah.

Jake:

So what that does is it basically allows you to make sure that there's never going to be duplicate file names. It doesn't matter, You know? And then when you need to download it or need to let somebody download it from your service, you just say, like, okay. We'll go grab the ULID at this location and then pull it out and save it as this. You could do that.

Jake:

Right? And that basically makes it completely transportable. You can put it wherever you want. It doesn't even matter. However, there's another part of my code where I'm taking pieces that I have generated.

Jake:

So let me just let me be specific, I suppose. Each day at, like, 1 AM, I generate a claim batch dot CSV, and I have a record for it in the UI where they can go download it. And that's the part that I control, and that's completely under my control. But I also have a secondary location that I push it to, that same CSV, where they can download it straight from, like, an s three bucket themselves. So they get the credentials to that s three bucket.

Jake:

If they don't want to come into the UI and download it, they can just hook up to s 3 and download it. That one probably has to be named whatever I'm gonna name it. Right? Like, 202411 dash 19 dash claim batch CSV, something like that. You know what I mean?

Jake:

Someone does have to be named. And so I kinda have to deal with both sides of the world there. I I I don't think it'd be super friendly to just drop, like, a ULID with no extension file name into that location. You know, it's gotta be named some sort of sensical way that they could figure out this is the correct file I'm looking for. So, yeah, I'm working through that part right now as far as how I'm gonna save it in the database because that is something that I'm doing really inconsistently across the board right now, and I'd like to just land on a way in which we're gonna do that.

Jake:

And so we'll see.

Michael:

Yeah. It'd be interesting to see where you land on that. But, yeah, it's like it's a consideration, but it may not actually be a problem. Right. It's yeah.

Michael:

It's

Jake:

not a problem yet. It's not a problem. Yeah. Because each of our each of our imports that we store use sort of like the Spassie media library way where it's like you know, Spassie media library, the way that they do it is they use an ID of the record itself in the media library. So there's an auto incrementing ID on the media table that you have from Spassie.

Jake:

So one through infinity. Right? And whenever something is attached to record number 1 in media library, it creates a folder of ID 1 slash and then everything gets stored underneath that and then 2, whatever. So instead of saying, like, hey. You know, instead of naming them with some UUID, they basically just say, I'm gonna create a subdirectory and then drop your file in there and that way we'll avoid any collisions.

Jake:

So they keep the original name when they save it as the value that's in, you know, in s 3 or wherever you're gonna have it. So that's cool. The other thing that's interesting too is, like, we are having each vendor, each tenant in the system has its own disk, in Laravel, but the neat thing about that is we can also allow people to host their own storage. So if they want to pay for their own storage, if they wanna put it in s 3, if they wanna put it in Cloudflare r 2, or if they wanted to put it in Azure blob, it doesn't matter. Like, we can push it wherever they want.

Jake:

As long as we have a driver for Laravel that suits that, doesn't make any difference, which is really cool. So some of the tactics was

Michael:

away from you as well?

Jake:

Correct.

Michael:

To to store those things.

Jake:

Correct.

Michael:

And which, you know, it would have compliance and whatever else, benefits outside of just, like, yeah, we're not paying for it. Well, no. It means that that that stuff gets pushed straight to their own thing, and they can access it in whatever way they need to access it, which is good.

Jake:

You hit the nail on the head though with the compliance stuff, dude, because that's exactly it. It's like, I do not wanna be responsible for some data loss, data leakage garbage. It's like, it's on their side. We are just a pass through. That's that's my goal.

Jake:

Right? So it's like for any partners that we have that are over x number of claims a month or something like that, we'll just require them to have their own storage. Yeah. Yep. Yep.

Jake:

Amazing. So it's been good. It's been good. It's been a good project. Really excited about it.

Jake:

The other thing that we could talk about in 2 weeks if we want to or we could talk about now is documentation stuff, but that's been a that's been sort of fun too, trying to figure out what we're gonna use for documentation. There's lots of libraries out there. Have you used any libraries for documentation stuff?

Michael:

I used like, I've used VPress, and I know that VPress was used for a while. So, James Brooks was was posting that they're starting to move the Laravel documentation things to Mintlify, m I

Speaker 4:

n t l I f y.

Michael:

So that's probably that's probably what everyone will use now.

Jake:

It's Well, so it's interesting. Right? So, I mean, I I don't want to be that guy, but should I be that guy? Go on. Okay.

Jake:

Alright. So Laravel gets venture money.

Michael:

Mhmm.

Jake:

Right? K. Then they have a Sentry integration on Forge. Sentry is also backed by the same venture company. Mhmm.

Jake:

Right? And then they move the documentation to Mintlify, which is also a venture backed company. Are we seeing a trend here? Right? I think it's sort of like a I scratch your back, you scratch mine sort of deal.

Jake:

All in

Michael:

the family kinda thing?

Jake:

Correct. Where it's like, hey. We need to redo our docs. Why don't we just use this other product that we also have investments in? Great.

Jake:

Let's go to Mintlify. You know what I mean? So it's sort of like, hey, everybody who's a Laravel user, we're now using Mintlify. It's like free advertising. You know what I mean?

Jake:

And so Yeah. That's kinda my take.

Michael:

I I

Jake:

don't even know that it says for, like, Mintlify as $1,000,000. What's that now?

Michael:

Low, free advertising for the low low price of $50,000,000.

Jake:

Right. Exactly. Exactly. But but you know what I'm saying? Like, Mintlify, I think, like, maybe it is or isn't the absolute best case, like, option for, like, your docs.

Jake:

But it's what they're using, and so it's, like, great. And it's fine. I mean, I looked at the platform.

Michael:

It depends on what

Jake:

kind of

Michael:

docs you what what kind of docs you're building as well. Like, if it's developer documentation, it's okay. But, like, the the hesitation is always unless it's, a, kept up to date, and, b, hosted somewhere that you can access it, you know, before you have for for onboarding, for example, if you've got documentation that you need to build before you can spin up a repo, that's probably not ideal. But, certainly, like, we we use ClickUp for some for most things, I think, because anyone can write that documentation. So we just mark down this this crazy week and things like that as well.

Michael:

But, yeah, It's always always interesting to to see that kind of stuff. But it it looks nice, Mintlify. It's Yeah.

Jake:

It really does. Explain

Michael:

it. It's, you know, it's the, the commercial not like, it's not a pay thing, but it's the commercial version of like, this is what happens when some money goes into a company building a thing.

Jake:

Mhmm. Mhmm. Yeah. The challenge and so how much time are we at right now?

Michael:

We're over. We're done. We're finished.

Jake:

We're over. Okay. So here, I'll give you the quick teaser version of it. Right? So we were looking at we were looking at documentation stuff and we were looking at VitePress, which I've gotta say, VitePress is freaking awesome.

Michael:

It's Yeah. It's pretty

Jake:

good. So good.

Speaker 4:

It looks really It's it's not down

Michael:

to get started. You can bolt your your view stuff in there as well. Like, Minnify is great if you want to pay, you know, to have it hosted for you. But I think I think VeePress is probably the way to go for most open source things and internal documentation and things like that would be easy enough.

Jake:

It really is so good. Now the thing I will say about it is that it's a little bit difficult to host within your existing application. Right? I said this is gonna be a teaser, so I promise it will be. But if you want to have it inside of your existing Laravel app, so if you have, like, myapp.com and and you don't wanna have docs.myapp.com, you wanna have, like, myapp.com/docs, which you can have for a number of different reasons, then you've got to do some work and some weird stuff to get VPress to do that.

Jake:

We have to, and this sounds so weird, our documentation requires login. You have to be logged in.

Michael:

Right.

Jake:

And it's just because of, like, some agreements that there are with these different, you know, carriers and things like that. They're very, you know, touchy and

Michael:

that sort of stuff. They don't want anyone to have access to their stuff directly.

Jake:

Correct. And so we have to have people who've been approved to be able to see it be able to see it. So we have to protect it behind Laravel's authentication stuff. And so we're currently in the process of moving over our VeePress documentation over to Prizet, which is a library that we talked about on air, for Laravel News not too long ago. So it, it's like a markdown implement, you know, it uses markdown and then it it looks very similar to VitePress, but, I think it uses, like, Folio or something behind the scenes, maybe.

Jake:

Vault, something like that. So interesting. Anyway, we can talk about that next time and we can also talk about, getting a Filament app to run at the root of your application while also using Jetstream and Fortify. Fun times.

Michael:

We can do that next time, because my video is frozen for those of you watching on YouTube.

Jake:

I saw that. Yeah. So

Michael:

just just trying to figure out this whole doc situation. I was saying to Chris Chris Faddow, like, watch out with that that, cam link because just hang on. I'll be right back. Apparently, I have frozen. So

Jake:

Yeah. No worries.

Michael:

Yeah. My recording stopped. You won't get my video back, but that's okay. We'll just deal with it. I

Jake:

No worries. Should I wrap this one up for us?

Michael:

Yeah. That's alright. I'll I'll I'll wrap it, and then yeah. I was talking to Chris for now about this thing. I said, be careful with your Cam Link going into a dock because they're they're incompatible.

Speaker 3:

And he

Michael:

goes, oh, it seems to be working. I'm like, yeah. It will work. In so far as, like, I plugged it in and it looked like it was working, but then as we have just seen here, or at some point, potentially just stop working. So Just stop working.

Michael:

We will wrap it here, I think.

Jake:

Sounds good. Do you want me to do it or is this still recording on your side or no?

Michael:

You you do it. Just in case it's not recording on my side.

Jake:

Sounds good. Everyone, thanks so much for listening to episode 166. You can find Shonas for this episode at northmeetsouth.audio/166. If you like the podcast, please please rate it up in your pod catcher of choice. 5 stars would be incredible.

Jake:

And if you have any questions, hit us up on Twitter at on x or on bluesky. I don't know if your handle's the same. I think mine might be close. Atjacabennett@michaeldorindaor@northsouthaudio. Alright, folks.

Jake:

Till next time. See you later.