Setup · 70:19
Setup, database and auth
Demo, project setup, Neon + Drizzle and Better Auth.
- Meet AI: video calls with AI agents.
- Neon Postgres + Drizzle ORM.
- Better Auth setup.
| Layer | Tool |
|---|---|
| Framework | Next.js |
| DB | Neon + Drizzle |
| Auth | Better Auth |
Do this in your own tools, step by step. Ticks are saved on this device.
Database?
Neon + Drizzle.
Auth?
Better Auth.
0:00 Whether it's a language tutor, interview coach, sales assistant, or something completely custom, the AI is there to actively help during the call. To start a new call with an AI agent, I click on the new meeting button. I'm going to name this one startup coaching call. I'll also create a new agent here called Hustle Coach. And just for fun, in the instructions, I'll tell it to be direct, hyperdriven, and a bit over the top, like a founder who just raised a seed round.
0:49 Once the agent's created, I can select it and I'm ready to start the meeting. With everything set, I click create meeting and land on the new meeting page. Right now, the meeting is scheduled as upcoming, which means I can come back to it later, cancel it, or start the call whenever I'm ready. So, I'll go ahead and hit start. That takes me into a familiar looking lobby just like Zoom or Google Meet where I can check my camera and microphone before joining.
1:14 Once I enter the call, our new agent, Hustle Coach, shows up right after. This is a live AI in the meeting with me responding in real time powered by Stream Video SDK and Open AI Realtime API. Hey, hustle coach. What makes a good startup idea? All right, listen up. A killer startup idea boils down to three things. Massive market potential, a unique value proposition, and scalability. You want a problem that's begging for disruption and a solution that screens innovation.
1:41 And don't forget, your model needs to scale like wildfire. If you can pitch it in one sentence and it sounds epic, you're on to something hot. Now go out there and disrupt, disrupt, disrupt. When the call ends, the meeting switches to processing status. Behind the scenes, background jobs kick off automatically, powered by ingest and agent kit. These workflows handle everything. Fetching the transcript, summarizing with AI, and saving the results back to the database. When the meeting is done processing, it's marked as completed, and all the content is ready.
2:28 First, there's the summary. A clean breakdown of what was discussed, organized by topic, and timestamp. Next is the transcript. It's fully searchable and when you search for a word, it highlights every place it appears. The whole call is also recorded and available to replay. And finally, there's a chat GPT like interface that actually understands the meeting powered by stream chat SDK. You can ask for specifics like who asked for advice and it will give you the answer.
3:15 Meet AI is a SAS product. So, it runs on a subscription model. Down here, you can see I've hit the limits of the free trial. When I try to create a new meeting, I'm redirected to a page with three upgrade options. I'll go ahead and upgrade. And that takes me through a quick checkout powered by Polar. Authentication is powered by better out a fully free and open-source out solution built for modern web apps. It handles email login, social providers, session management, and even a seamless integration with Polar, our payment infrastructure.
4:04 Our app is also fully responsive. Every screen adapts cleanly to mobile. Models and dropdowns turn into mobile drawers for a smoother experience on smaller devices. In this course, we won't just write the code. We'll also follow a proper Git workflow throughout the tutorial. Each chapter ends with a new branch and a pull request reviewed automatically using code rabbit AI. Let's quickly go over the test stack. We'll be using Nex.js 15 with React 19 together make our full stack framework supporting server components and serverside rendering.
4:51 TRPC for full stack type safety used together with tanstack query. Drizzle OM with Postgress provided by Neon for the database. Tailwind version 4 for styling combined with Chats UI for accessible and reusable components. Better out for authentication. Polar for payments. Stream for video and chat SDK. Ingest for background jobs. Code rabbit for AI powered code reviews. And finally, Open AI for real-time agents and AIdriven features. And of course, we'll deploy everything to production when it's ready.
5:14 And now, without further ado, let's get started. In this chapter, we're going to go ahead and set up our project. This will include configuring Nex.js, JS, confirming our environment, installing Shhatzy UI, and finally pushing our project to GitHub to introduce some Git workflows. Let's start with Next.js. From their official installation guide, we can find some system requirements. Let's go ahead and confirm that we have the proper Noode.js version. Purther instructions, it needs to be at least 18.18 or higher than that.
6:00 You can go inside of your terminal and run node-v. If you have a lower version or you've gotten an error running this command, you most likely have to reinstall NodeJS. You can head to nodejs.org and simply install the latest long-term support version, which is in my case 22.15.1, the exact same I'm using. After that, you can restart your terminal and run the command again to confirm. And while you're there, it's a good idea to also confirm these two commands, npm and npx.
6:25 These two commands come alongside node. So you will automatically have them installed, but it's always good to double check. Once you have confirmed those three commands, you are ready to install Next.js. In their automatic installation chapter, they instruct you to use the create next app with the at latest version. The latest version at the time of me building this tutorial is 15.3.2. So instead of using at latest, this is what I'm going to do. npx create next app at 15.3.2.
7:14 The reason I'm doing this is so that you the viewer is completely aware of the version that I am using because I don't know if you found this video 6 months from now or a year from now. In that case, the at latest will be significantly different than the one I am using. So my advice to you, if you want to follow this tutorial exactly as I am, use the exact same versions that I'm using. So I'm going to be using create next app at 15.3.2.
8:01 Let's call our project meet AI. And now we have to select some options. You can use arrow keys to select between yes or no. For TypeScript, select yes. This is crucial. Slint is also yes. Tailwind is also yes. Source directory should also be yes. Make sure to change it if no is default. App router also yes. Turbo pack also yes. And the only option I will leave at no is to customize the import alias. I don't want to customize it.
8:25 I will leave it the default. Let's wait for the dependencies to install. Once you get the success message, you can go ahead and enter the new directory. Change directory meet AI. And inside you can enter ls command which should list all the files and folders inside. Now that you've done that before we run the project let's quickly set up our IDE. In my case that will be Visual Studio Code. So I'm going to select open and I will select the meet AAI repository.
8:52 If you get a big prompt asking if you want to trust the authors you can select yes here. Now let's quickly go inside of package JSON and confirm the versions. React 19, next 15.3.2, TypeScript 5, and Tailwind version 4. Now let's quickly confirm our config files. TS config, host CSS config, next config, and slant config. There is no Tailwind config because thanks to Tailwind version 4, we have one less config file which is absolutely amazing. And also confirm that you have the public folder.
9:44 Confirm that you have the source folder and inside the app folder with favicon globals layout and page. Once you have confirmed all of that, you are ready to start the app using npm rundev. And you can head to localhost 3000 to see the result. Depending on the light or dark mode, you might see a white or black background. Now, let's go ahead and learn how to change something. Go inside of the AMP folder, page.tsx. And you can remove everything from the return method.
10:30 And you can remove the image import. And instead, just return a hello world. And there we go. You should see your change the moment you save your file. Now let's quickly try out Tailwind. So I'm going to go ahead and write some class names. Text for Excel font bold and text green 500. And you have probably immediately noticed that I have some help writing this tailwind. I have autocomplete. I have the color helper. And when I hover over classes, I can see the actual CSS.
10:55 If you're interested in having the same help, go ahead and install the Tailwind CSS IntelliSense, this package right here. It is immensely helpful when writing Tailwind. Go ahead and save this file and immediately you should see your new Tailwind changes. Perfect. What we have to do next is we have to install ChatsN UI. What is Chatnen UI? So it is a set of beautifully designed accessible components and a code distribution platform but it is not a component library.
11:43 Instead it is how you build your component library. Let's go ahead and add it to our project to understand a bit better. I'm going to click installation next.js and instead of using at latest I'm first going to confirm what is the actual latest version. So you can use the same version as I am. So I will just do d- version here. And there we go. 2.5.0. So npx shaden at 2.5.0 in it. Make sure you're doing this inside of your project.
12:07 Go ahead and select neutral for the base color. and go ahead and select d-leacy pure depths as the solution in case some packages fail. Why would any packages fail? Because we are using React 19. React 19 is the latest React version at the time of recording this video, but not all packages have adapted their peer dependencies to support React 19. And while they're still probably working inside of React 19, installing them throws warnings in some cases errors which completely break the installation cycle.
13:00 So you have to override them by using either d-force or d- legacy peraps. In our case, we will use d- legacy peer deps. So select the arrow keys and choose d- legacy pure deps and wait for the installation to complete. Once the installation is completed, you will be able to go back to your project and you will notice some new files here. If you're wondering exactly which files are new, you can click in on this little source control icon and you will see everything that has changed.
13:25 So some of this was changed by us. For example, this page which now only displays hello world. So obviously we are not interested in this. But we are interested in the new utils file which seems to have added a new function called CN which is actually short for class name or class names which we will be using to safely merge, combine and dynamically add tailor wind classes. It's going to come in very very handy. So that's one of the files that our chat init command has added.
14:13 Another thing it has modified is our globals.css. What it modified it with is adding an actual theme for our project and we will be able to modify this theme and then our project will look unique later on. And it also installed a couple of packages like class variance authority clsx lucid react uh tailwind merge and I believe one more tailwind animate css everything else was already here but uh it might have moved position like next you can see the next version didn't change it just moved the position so don't worry the next version was not modified and we also have the components.json JSON which you can think of as a config file for chat and UI and I didn't mention but also or did I uh lucid react these are our icons which we will use for the project but we still can't really see any components here and they instruct us to add a button component here.
15:00 So while we can do that two things that will annoy us throughout this project is first of all remembering what is our version and the second one is remembering to choose d-leacy peer depths every time. So instead how about we add all components at once and then later just get rid of those we don't need. So we only have to remember the chatsen version one more time and we only have to select d- legacy peer deps one more time as well.
15:47 So I will select this and I will select d- legacy peer deps one last time and let's wait for this to install all dependencies. And there we go. All of these components have now been added to our project. You can go inside of your source components UI and you will see all of them here. And that's the power of shhatsen UI. They are not just added as npm packages. Instead, they are actual coded components inside of your project, which gives you the power to customize every single last bit of them.
16:11 And that's exactly what we will do in this tutorial. So, let's go and try one component out. Let's go inside of the app folder page. Instead of returning a div, let's return a button from components UI button. In case it's your first time seeing the add sign, it's basically an alias which makes it easier for us instead of doing this all the time. So basically the alias sign moves the import to source if that makes sense.
16:57 you will see uh it will make more sense later as we work with the project. And now let's go ahead and add click me inside. Once you save this and go ahead and mpm rundev your project again, instead of the hello world, you should now see a click me button. And if you add a variant here like destructive, it will change its color. But the cool thing is if you click command or control and click on the button to enter it or of course manually go inside of source components UI button you will be able to add or change any variant.
17:22 For example, after link, make sure you have a comma, and add custom text white, background, purple 500, border two, and let's do border red 500. Now, let's go back to the page. And what you will notice now is that it has automatically been added to the types here. And there we go. We now have our fun funky new variant. Of course, we just used that for demonstration. You can remove that now. And you can see how you immediately get an error here.
18:11 Great. So, we now learned how to add Chatsen components and how to use them. And we've also learned the difference between your usual component libraries and Chatzen, which allows us to actually see the code behind each component and modify it to our liking. One more thing we have to do is push this project to GitHub. So before we do that, we have to commit all of our changes. And there's quite a lot of them here. Since I'm using Visual Studio Code, I will click on the source graph here.
18:36 And I will simply use the plus icon to add or stage all of these changes. This is equivalent to get add dot command. Once all of these have been changed have been staged you will find them under the staged changes accordion and then you have to enter a commit message. In my case I follow the following convention. This is chapter01 setup. So I'm going to call this 01 setup as well. And I will simply click commit.
19:24 That's it. I'm not going to touch anything else. We still haven't pushed this to GitHub, but now we are ready to do so. So go ahead and click create new new repository and you will see this screen. I'm to call this meet AI and I will select it to private and I will create a repository. After that I'm going to go ahead and select the second option which is push an existing repository from the command line.
19:49 So just copy these three lines here. go inside of your terminal. You can shut down the app. You shouldn't have any numbers here or anything because uh nor should you have any numbers here. Basically, it should all be committed. And just paste those three lines. And once you've done that, refresh. And there we go. Your project is now on GitHub. And you are ready to follow the proper Git workflows. And you can create pull requests, branches, everything.
20:12 Perfect. You can go ahead and check inside of your source app page. And inside of here, you should have a button with click me. Perfect. So, I think that wraps up our setup chapter. We have set up Nex.js. We confirmed our environment. We installed Shatsen UI. And we pushed our project to GitHub. Amazing job, and see you in the next chapter. In this chapter, we're going to go ahead and set up a database and an OM for our project.
20:58 Let's get started and let's obtain a Postgres database using Neon. You can visit neon.te or you can use the link in the description to let them know you came from this video. Let's go ahead to the Neon homepage and let's quickly create or log in using Google. After you are inside of your dashboard, you will be able to create a new project. I'm going to call this one meet AI and I will set the database name to meet AI as well.
21:22 Once I create the project, I can click on the connect button and this will help me obtain my database URL connection string. Once you've obtained that, go inside of your project and create a new environment file in the root of your application. Go ahead and create a database URL. And inside of the quotes, simply paste the copied snippet. It goes without saying that you should never share this with anyone. All environment variables that I will be using are for this tutorial and it will be removed after this tutorial.
22:12 You however should not share this with anyone. Make sure you didn't misspell database URL here. And also do one more thing. Confirm that your environment file is a little grayed out. That means that it's added to Git ignore and that you will not be able to accidentally commit it. Great. After you've added the database URL, it is time for us to set up our Drizzle OM. So, let's go to orm.driel.te theme or use the link in the description to let them know you came from this video.
22:36 So, let's go to Drizzle ORM here. Let's click get started. New database Neon. And now what we're going to do is we're going to install some packages. What I've prepared here is the versions, right? So, what we're going to do is we're going to prepare and without pressing enter, we're just going to go ahead and get the latest versions of each one. Just in case you're watching in the future, you will know what versions I'm using.
23:00 So drizzlem04 43.1 neon database serverless is 1.1.1.1 and my environment is 16.5.0 and I will also add [Music] d-leacy-per depths. So this is all in one line and this will basically help me avoid those errors which I was talking about regarding peer dependencies. Please use this line otherwise you will get an error. If you get an error no worries just try again and add- legacy pure depths. After you run this command you should have three new packages.
24:11 Let's go inside of a package JSON. We can check here as well. Neon database serverless environment and drizzle ORM. There we go. So neon database serverless is version 1.0 environment 16.5 and Drizzle OM 0.43.1. Perfect. Now let's add Drizzle Kit and TSX as our dev dependencies. So the drizzle kit version I will be using is 0.31.1 and the TSX version I will be using is 4.19.4 and let's add legacy here deps here as well. This will add these two packages right here in the dev dependencies.
25:02 We now have Drizzle Kit and TSX. Great. Now we can close all of these. I mean, you didn't even have them open, but I will close them. We've already established step two, adding the connection variable. So, we can go immediately to step three. I'm going to copy this snippet here, and I will go inside of source database folder and inside an index DS. Let's paste this inside. And I'm going to change this to double quotes and I will add an exclamation point here at the end.
25:27 And I will do export const database. One thing I want you to double check is go inside of your environment, copy this key and paste it here because you would be surprised how easy it is to misspell this and no errors will be thrown if you for example put an I here instead of an L. It just won't work. So, what I recommend is just copy it from here and then paste it here. There we go.
26:14 And add an exclamation point to get rid of the error. Great. Now, let's go ahead uh and do the following thing. So, in here, we we are okay with using neon http. Uh if you need a synchronous connection, you can use the neon database serverless. We have it installed. So, if you want to uh you can do it like this as well. Great. So now what I want to do is I want to create a table and we can do this exactly.
26:38 So I'm just going to copy whatever they did. Source databases schema.ts. Let's go inside of schema.ts. There we go. And this really doesn't matter because we will remove it later. But for now, yeah, let's use integer pg table and vchart here. uh and for the id it will be generated always as identity here this will be unique uh and these will be integers and these will be vars with a fixed length once you've done that we have to set up a drizzle config file so we can copy this as well and create drizzle doconfigts in the root of our application there we I'm going to go ahead and just modify these two double quotes.
27:26 I love using double quotes. There we go. And let's just confirm that this is correct. So my out will be uh slashdrizle. My schema is at source database schemas. Let's double check source database schemas. My dialect is Postgress and my database credentials are correct. And once again, just double check database URL and just add it here. Make sure you have the Drizzle config outside of any folders here. Great. And now what you have to do is you have to apply the changes to the database.
28:13 The easiest way to do that is by using npx drizzle kit push. Alternatively, there are more advanced methods such as generating the actual migrations and then applying the migrations. But since we are not working in a team, we are working solo. This is just a tutorial. We're going to keep it simple and we will directly push our changes to the database. So let's go ahead and clear this and let's just do a comparison. So if you go inside of your neon now and go inside of your tables here, you will see that for the meet AI, there are zero tables in the public schema.
29:01 But if I do npx drizzle kit push right here, you can see that it pulled the schema from the database and it applied the changes. So if I try refreshing now, I have the users. The user has an ID, name, age, and email. There we go. Perfect. So, we've added Drizzle OM, we've added the schema, we pushed the schema, and we verified the changes in Neon. But one thing that we didn't do is verify changes in Drizzle Studio.
29:28 So, let's go ahead and do that. Now, using a similar command, npx drizzle-kit, instead of push, you can type studio. And in here you can click on local.drizle.studio. So you have two options. You can either locally use the drizzle studio like this or you can use them in the neon console. There we go. So these are in sync. They are the same uh studio. Amazing. Right. And now what I want to do is create some scripts just to help us in the future.
29:54 So let's go inside of package.json JSON here and let's go ahead and add database push and let's map that to drizzle-kit push and database studio will be drizzle-kit studio. So now instead of doing npx I don't have to do that anymore because drizzle kit is a part of our dev dependencies here. So instead I can do npm run database studio like this. It's going to be more generic. So later on if for any reason you replace your database you can keep the uh command that you can keep the familiarity with your command.
30:41 Right? And we are also not going to have to remember this command anymore. npx drik studio. We can just use our database push then database studio like that. Excellent. So I believe that is it. We have verified the changes in the studio. Now what we have to do is create, review and merge this pull request. Let's go inside of our source control here and under the changes, let's click the big plus button and this will mark them as staged changes and this is zero to database.
31:28 I believe it is. So I will press commit and since we have already connected with GitHub this time uh what we can do is we can check out to a new branch and I'm going to call this 02 database. There we go. So I have committed but I'm in a new database because I didn't push yet. In case you already pushed, no worries, okay? We are just learning the git workflow here. You can do the branch process in another chapter.
31:52 It's completely fine. No worries. But uh if you didn't push, you can create the new branch using the IDE just like I did. And I will just click publish branch. That's it. And now my branch will be published. So I'm going to go inside of GitHub repository and see what happens. Inside of my GitHub repository, you can see that I have a new branch with recent uh pushes here. So I will click compare and pull request.
32:16 But just in case you don't have this, you can go inside of pull requests manually, click on new pull request, keep the main as base, and select your new branch here just in case you want to do it manually. And then click create pull request. And I'm going to now click create pull request. Now in here, uh yours will probably look like mine was a second ago. you probably don't have Code Rabbit. So, what is Code Rabbit?
33:06 Code Rabbit is an AI tool which will uh almost act like a teammate for me and it's going to review all of the changes that I just added here and it's going to give me a summary of what I just did and also some comments, even some potentially breaking issues. So, it's a very useful teammate for us. And we're going to see our code being reviewed by AI for each chapter. So, we know we didn't commit any bugs.
33:31 And you'd be surprised. In my last tutorial, Code Rabbit caught so many bugs. I was shocked. So, I'm excited to see what it will catch. Now, I'm going to pause the video and play it when it's finished. And here we go, a summary by code rabbit. We introduced some new features. Integrated Drizzle OM and the Neon database support. We added a what is a temporary database schema for users including fields for ID, name, age, and unique email.
34:19 We've also added some environment variable management for secure database connections. So, no worries. It did not detect a new environment variable. It detected that we're using it for database connections. So no, we did not commit any environment variables here. And we also detected some chores such as new scripts for database migrations and studio access. And we in here we have a more in-depth walk through. Uh specifically we have changes file by file exactly what we modified and how.
34:44 And we even have a sequence diagram which will in become increasingly useful as we add some complex things. Right now the only sequence it can create is our app connection with the neon database through Drizzle OM. But later on when we add some hooks and components, it will create equally if not even more useful diagrams to help us understand that. And in here we have some actionable comments. As you can see here, it recommends adding an environment variable validation for database URL.
35:09 Basically, inside of our let me see index here, we put an exclamation point here because we just know that the database URL will exist. But Code Rabbit recommends doing an if clause and throwing an error if it's not set. And then we can use it without uh the exclamation point. It also recommends using the Neon database serverless driver. So in our case, I'm fine the way it is. Uh I'm always open to suggestions like this one.
35:59 But uh this is how I initially built the project and I didn't have any problems whatsoever. And I think it's okay because with if we are missing the database URL, nothing is going to work either way. So we don't have to put an explicit if clause for that. And as per database uh neon database serverless well using the drizzle you know configuration here we can see it's fine to use neon http serverless is if we want a synchronous connection more specifically if we want to use websockets.
36:23 Uh but it's completely fine to use neon http for this tutorial. Let's see what else it gave advice for. So in here I think it's the same thing. It's recommending an if check for the database URL. Of course, a good suggestion, but as I said, if this is missing, everything will break anyway. And here's an interesting thing. So, it actually detected that some issues were opened in Drizzle or Drizzle Kit where they had a mismatch between Drizzle Kit and Drizzle OM.
36:48 So, our Drizzle Kit version is 0.31 uh and our Drizzle RM is 0.43. So, it's telling us to be careful here, but it's completely fine. Uh, they don't have to match exactly. Perhaps that was an issue previously in some previous versions, but it's completely fine. You can see it's working with no problems whatsoever. Great. So, I'm ready to merge my pull request. We got a very good review. Uh, and this is how we are going to review our code every time.
37:39 Great. So once you have merged this, you will see this says merged. And you can now go back to your code and you can change your branch uh back to main like this. And you can press this and click okay. And it should synchronize your branch with main. And when you look at your graph here, you will see that we had our 01 setup commit and then we branched out into a new version uh I mean into a new branch and then we merged that pull request back here.
38:03 So it's important that next to your main branch here you don't see any numbers. You can click this button as much as you want. It will simply recsynchronize. So, make sure you don't have any weird numbers here or any numbers here. Make sure your graph looks like this. And that means that you are ready to go onto the next chapter. Amazing. So, if you want to have code reviews like this, you can visit coder rabbit.ai or use the link in the description if you want to let them know you came from this video.
38:50 I highly, highly recommend this, especially if you're working solo and have no one to review your code. There we go. So, let's go ahead and wrap this up and see you in the next chapter. In this chapter, we're going to go ahead and create our authentication setup. We're going to be doing that using better AL. We're going to configure the new ALF schema. We're going to push those changes to Neon database. And we will create a very basic temporary UI which will allow us to create a new user.
39:15 And we will finally create review and merge the pull request for this chapter. Let's start by adding better out. So you can head to better-al.com or use the link in the description to let them know you came from this video. So we're going to go ahead and click get started right here. And if you want to read more about Better Out, you can read it here. It's an absolutely amazing library. I I have not seen a library as good as this in a while.
39:40 So, I'm going to go inside of the installation tab here, and we're going to do mpm install better out. And just for this project's longevity sake, I will use an exact version uh 1.2.8 like this. And let's see. Uh, I forgot to add d-leacy peer depths. So, of course, we get an error. So, let's repeat this. But let's add d-leacy peer depths. And let me confirm that this was the correct version 1.2.8. It is. There we go.
40:31 So, when I add d- legacy per depths, we have no error whatsoever. Great. Now, let's go ahead and let's add the better secret environment variable here. So I'm going to add this and you can add whatever you want inside or you can use the button generate secret here and just copy whatever is here. It really doesn't matter but it must not be empty. You need to write something inside. For production obviously it would be a good idea that it's something the length of this rather than just you know secret.
40:55 Uh but for development it doesn't matter. Just make sure it's not empty. Let's also set the better out URL here and we can set it to be localhost 3000 under the HTTP protocol. So it's important that you know the protocol of your app and you can find it every time you do npm rundev. In here you can see my protocol is http localhost 3000. So you can copy this and add it here. It needs to match.
41:47 Great. And now let's go ahead and let's create a better ALF instance. So the place I'm going to do this is inside of source and inside of lib I will create ALF. DS and I will simply import better from better out. And I will export const here. And let's quickly just visit my package JSON just so you can doublech check my versions 1.2.8. There we go. Now let's go ahead and configure a database. As you can see, it immediately offers Postgress here, but we will actually be using Drizzle.
42:13 So it has an option for that as well. Of course, it does. So I'm going to add the Drizzle adapter here from better al adapters. Drizzle and I will import database from at / database which is our Drizzle instance. So this is the exact location that my database is in database index. Now that we have both of them we can add the database option here and we can select the provider to be PG which stands for posgress.
43:02 Of course, since we are using Posgress, this is the correct option. Let's see what else we have to do. Now, we have to create the database tables. So, better out includes a CLI tool to help manage schema required by the library. So, you have two options to create the actual schema for your authentication. If you want to, you can use npx better al cli generate or you can manually create it by going inside of the database section here and you will see every single database item that we have.
43:25 What we are going to do is we are going to use the CLI here. So we are just going to use the generate one. We are not going to use the migrate one because we will be pushing directly to the database. Now, for longevity sake, I'm also going to show you the version at the time. It looks like the version uh of better out CLI needs to match the better out. I'm not sure if this is a coincidence, but it makes sense that these two match.
44:11 So, yes, the version I'm using is 1.2.8. And we don't need d- legacy pure deps here because we're not installing anything. We're just generating. Uh so, let's click generate and let's see what happens. I have to install this package first 1.2.8 and let's see what will happen once this completes. So it's asking me do you want to generate the schema to do /all schema ts. I'm going to select yes. I want it to be in a separate file so it doesn't accidentally overwrite whatever I have in my schema.
44:34 So I will press yes. And there we go. Schema was generated successfully. So now what we're going to do is we're going to go inside of the out schema here. We can remove integer. We don't need it. And now uh what I want to do is I want to copy things just one by one from out schema to my source database schema. So instead of this users, you know, we will have an actual user here. So we can remove this actually.
45:19 Uh, and we can also add this here. There we go. Uh, and what I would like to do is just fix the indentation of these so it looks a little bit better. There we go. Like that. After we defined our user, let's add our session. So the reason I'm doing it one by one is just so we are a little bit more aware of what we are adding to our schema and I'm just formatting it a little bit.
45:42 So what do we have so far? We have the user here and we have a session and you can see that session has a relation to the user and once the user it's deleted the session will be deleted as well thanks to the cascade method here. We also know that uh the email has to be unique for example. So that's why we are going one by one just so we're a tiny bit more aware of what's going on here.
46:07 Now let's copy the account one. So the accounts will be used for social login here. Uh let me go ahead and fix the indentation on this one here. And this one is pretty simple. So it has a relation to user as well. And let's add the verification which looks like to be the last one here. And verification is self-explanatory. If we want to add verification, we have the table for that as well. Uh there we go.
46:33 So one, two, three, four tables. It looks like we've added here. So let me just confirm here. One, two, three, four. We did not miss any. So we can now go ahead and remove the out- schema. We no longer need that here because we have added it to our schema right here. Uh and it looks just fine. Let's see what else do we have to do now. So the next step here is to migrate. But we are not doing migration.
47:24 We don't have to do that. We have our script for synchronizing with the database. And that's going to be database push. It's much simpler uh this way. So it looks like uh we can do that already. So let's do it. Let's see if we will encounter any errors or will this work uh by itself. So I'm going to try and do npm run database push. I think we might actually encounter some uh errors here. So actually no errors but we do have a question.
47:50 Is account table created or renamed? So uh this is asking us a question because we previously had uh the users table which we deleted right. So we have two options here. If you want to you can just nuke the database from neon and just create a new project with the new database and have a clean slate. Right? But what you can also do is just answer to these questions. So I'm going to try answering the questions.
48:17 If it seems to be okay, no problem. But if you for whatever reason think you've messed this up, you can always just create a new database and just obtain uh a new database URL. Paste the new database URL, run the command again and you won't have these questions. So the account table is a new table. So using the arrow keys, I will select the plus option and press enter. Same for the session. The only thing I will uh say is the users.
48:40 So the users have actually been renamed here and the verification has been uh added. Now in here uh is email verified column created or renamed. Uh so this is a create created column. Image is the created column. Created at is created updated at is created. Uh and looks like at the end of all of that uh I got some errors. So, I'm not exactly sure if this worked correctly. So, that's why I wanted to tell you you don't have to worry even if you mess this up like I did.
49:29 What you can do very simply is go inside of your settings here, just delete the project, right? So, you have to learn how to work with your database here. Of course, obviously, this is just for early development phases. You would not consider actually doing this in production. You would have proper migration status, right? But let's just try again. Meet AI 2 for example and let's click create and again let's click connect and copy the snippet and in here let's just paste this here.
49:52 So just make sure you have the new database URL and you don't have to change anything else. Let's do npm run push now and let's see if we will have any errors. No errors at all because this is a completely clean database. And if you go inside of your tables here now in Meet AI 2, you have account, session, user, and verification. Those four tables which we just added. So even though we could probably work our way around this issue and resolve it, I just want you to see how I actually do these kinds of things.
50:41 When I develop things, I often get into these kinds of conflicts. Since I'm in early development phases, I can just nuke my database and speed up the process. Again, please only do this in early development phases like this one where we are just learning how all of this works. Excellent. So, we have done the following. We have configured the out schema and we have pushed the changes. Uh I'm not sure if we can mark this as completely integrated.
51:04 I'm going to check this one last. Let's see what else we have to do. So, we now have to add some authentication methods. We are going to add social providers later. The first one we're going to do is the normal email and password. So let's go inside of the out here and let's add email and password enabled. True. And just like that we have enabled normal email and password. But besides that you have pass key, username, magic link.
51:28 You have so many different ways of authenticating here. And that's only uh what they provide you with. There's also the community plugins. So it's it's absolutely insane. Now what we have to do is we have to go inside of app folder API out. So let's quickly go ahead and do that. Source app folder let's create a new one called API and inside inside of square brackets out. So we are following instructions exactly as they say which I've messed up my apologies.
51:52 out without square brackets and then inside of square brackets three dots all. So this is kind of a catch all route and then finally inside of that a reserved file name in nex.js route.ts which represents an API. So we can then copy this and paste it inside. So we are registering our AL client here to post and get route for our localhost 3000/ API/ and then whatever comes after it. This is like a catch all universal route.
52:41 Excellent. So now that we have that, we also have to create the client instance. Uh so let's go inside of our lib here. The same way we created ALF, we will now do ALF-client.ts like this. And we can just copy this entire thing here and paste it. So the base URL of the server, you can see it says optional if you're using the same domain. So you actually don't need this at all because we are on the same domain.
53:04 And finally, you now have uh uh you can now Yeah, my apologies. No, I thought that this was an example, but um they are showing you that you can also export individual methods and hooks from create out client instead of exporting the entire AL client, but I'm fine with this way. And there we go. So that's it. You are now ready to use better AL in your application. continue to basic usage to learn how to use the ALF instance uh to sign in users.
53:54 So let's go inside of the basic usage here. And what we're going to do is inside of page.tsx here, we will just create a very simple uh form here. So I'm going to mark this as use client so I can make it reactive and add some hooks here. And I'm going to add email set email use date. And then I will do the same thing for name. Set name and password. Set password. Obviously uh this is not how we will build forms.
54:19 But what we we are doing now is just a very very basic confirmation that our uh better out has been integrated properly. So what I'm going to do here is just a div and then I'm going to add an input from components UI input which we have because we added all components from chats UI. I'm going to give this a placeholder of name. This one will be email. This one will be password with a type of password.
55:08 And I will just go ahead and give this one a value of name. and on change event target uh value. And I will just copy these and add them down here. There we go. Uh oops, I completely forgot to actually wrap this. Uh so this will be set name. This will be set email. This will be set password. The value here will be email and the value here will be password. I will just collapse this so you can see better.
55:56 Okay, I just collapsed these elements so you can see them better. And let's go ahead and try it out. All we need is a button here which will say create user. So I'm going to do npm rundev and I will visit my localhost 3000 which should now show my very simple form. Here we can give this a class name padding four flex flex column and gap y of four just so they have a little bit more space here.
56:24 And what I will focus on here is my network tab. I want to see what's going on here as well. So what we want to do now is we want to learn how to use better out here. So let's import out client in here. And let's use the out client in our onsubmit method here. So what I'm going to do is call out client dot sign in and let's see if is that the correct one? My apologies.
57:11 It is sign up email. And inside of here I have to pass in the email. I have to pass in the name. and I have to pass in the password. So these are the three required ones. You can also pass the image if you want to and the callback URL. And let's also add these right here. So on error, let's do window alert. Something went wrong on success. window alert success just so we are aware of what's going on.
57:58 Great. So now that we have this um let's go ahead and try submitting. So const on click on submit. So I think by default we should get an error here just by clicking this. Let me try. There we go. something went wrong. Obviously, we get an error because we have an invalid email because the email was not passed at all. So, I'm going to set my name to be Antonio, my email to be Antonio at uh demo.com.
58:22 And let's use the password to be password. One hint, your password needs to be I think at least eight characters, otherwise it will throw an error. So, if I just do one to three and click create user again, we have an error here. password is too short. So try 1 2 3 4 5 6 7 8 and let's see again something went wrong. Let's see what exactly it is. There we go. So uh this one wasn't exactly clear from the return here from the network tab.
58:46 But if you go inside of your terminal, you will see some errors. Server error, weather out error, drizzle adapter, the model user was not found in the schema object. Please pass the schema directly to the adapter options. So this is what I was waiting for because I knew that my AL configuration looked a little bit different. So I was waiting for the reason why. And it looks like because we need to add our entire schema. So let's import asterisk as schema here from at database schema and let's go ahead and pass the schema here and simply spread the schema like that.
59:35 So we have now connected our schema user session all of these things with the schema here. And I think that if you kind of like try and rename something here, you might actually get an error here or not. Maybe not. But let's try again now. So I'm going to try Antonio. Antonio demo.com. And 1 2 3 4 5 6 7 8. Create user. Looking promising. And there we go. Success. 200. And we can now go inside of our neon console here.
1:00:25 Refresh this and go inside of user. And there we go. You can see the actual user. So Antonio demo.com. You can see when we are created. You can see the matching account with the credential provider ID because we didn't use the social login. We used credentials. And you can also see the active session because we are automatically logged in actually. And the verification doesn't exist because we didn't add anything regarding verification. But yes, this is the part that was missing adding our schema here.
1:00:49 Uh and one more thing I want to check here is is there a nice way to maybe display that we are logged in. Uh let's say uh can I check let's actually try and follow the documentation here. So this is sign in. Okay, that works just fine. social sign on. How do I actually see the session? That's what I'm using. There we go. The session. So, I'm just going to go ahead and add this here from outclient use session.
1:01:37 All that I care about is the data which remaps to session here. So what I'm going to do is I'm going to check if I have a session. We are going to return a div here with a class name flex flex column padding four and gap y of four and I will add a paragraph logged in as session do user name like this and let's add a button here sign out on click and I think we can just do outclient sign out here like this.
1:02:29 There we go. You can see that in initially it shows the the register. That's because this is an actual fetch request. So it's loading for some time. You can of course extract is pending here if you want to handle that. But this is just for demo. And when I click sign out, uh there we go. And the cool thing now is that if I try registering again, I will get thrown an error because this email is already taken.
1:02:55 User already exists. Perfect. So the only thing that's missing here is a way to uh log in. So let's quickly add this as well just for fun. Let's do it. Let's do a class name here. Flex flex call. Yep. Y10 and we can just copy this entire thing and paste it below and this will be login. This just needs the name and onsubmit will be on login here and let's just copy onsubmit here. Let's call it on login outclient sign in.
1:03:19 Looks like we can also use email just like that. There we go. So let's try this. Let's try antoniodemo.com. And yes, both of them will be filled, but that's completely fine. Let's try the wrong password first. Password. Click login. Something went wrong and I didn't open my network tab. But I'm pretty confident that we got, as you can see from the code 401. Let's try again. invalid email or password. Now let's try actual password here. Actually 1 2 3 4 5 6 7 8.
1:04:06 Let's try logging in. And success. There we go. Logged in as Antonio. Just like that, we have implemented credential out. And it only gets easier from here. This was the hardest part of our authentication. Absolutely amazing amazing library. Uh, and of course we only tested this in the client mode because it's just, you know, easier to create a form here and add all of these callbacks and things, but you can have equally uh good developer experience with server components and their server util and we will use that later on.
1:04:55 But as I said for this chapter, I just wanted to build like a very dirty basic UI to ensure that we can actually create the new user. And now let's go ahead create review and merge this pull request. So I'm going to go inside of my graph here. My apologies my source uh source control here. Uh and I'm going to go ahead and add all changes and I before you commit you can open the branch whenever you want.
1:05:20 So you can for example add the changes make sure they are in staged go ahead and click uh checkout to and then create a new branch. So, I'm going to call this uh 03 authentication setup. I think that's the branch name. Yeah, authentication setup. And the message will be the same. You can see your branch is down here. You can click commit here and you can publish your branch. As simple as that. So, your branch is now available for review.
1:05:43 Let's go ahead and click compare and pull request. And let's create a pull request. And in a couple of seconds we will see the review by code rabbit. And here we have the summary. So new features. We have introduced a complete authentication system with user sign up, login and sign out capabilities. We have added a user interface for authentication including forms for registration and login as well as conditional rendering based on the authentication status, a new API endpoint to handle authentication requests and we have expanded the database schema and of course the new authentication library dependency.
1:06:31 In here, we have a more in-depth walkthrough as well as file by file change and a sequence diagram explaining how our current form actually works. So you can see here that when we fill up the sign up or sign in form, we call the sign up or login method which actually reaches the API al route which then handles the AL request and then using the uh to the database it validates or stores the user session and account entities and then it equally returns that state back to the user and the UI.
1:07:18 Of course, it left a ton of comments in regards to our form because that is just a temporary form which is missing a ton of things. So, naturally, all of these recommendations are correct. But no point in resolving them because we will be deleting that entire component uh in place of a proper one here. But if you're interested, you can pause and read just to see how this AI bot actually works because it is quite impressive as well as the suggestions it gives you.
1:07:41 Uh, excellent. And it actually refactors like your entire component, but we will be doing that later. So, no need to accept this. Uh, in here, it adds some suggestions for our schema. And regardless if this is uh more correct or not, I don't want to change anything because I want this to be strictly compatible with better out. I don't want to, you know, uh, accidentally mess it up. Uh great. Uh so in in here it marked a potential issue.
1:08:32 Sensitive credentials stored as plain text. I think that is a confusion because this is called text. That doesn't mean that what's stored inside is not encrypted, right? It is just a text type. This is true. It could be a varcher with a uh token limit. But I think they do exactly that. They encrypt it, but they just store it under a text type from Drizzle. All of these other suggestions are semantic or new syntax here. So, I'm going to go ahead and merge this pull request because I am satisfied with this result.
1:08:55 Excellent. Once you have merged this, go back to your IDE here and switch to your main branch. So you just have to find the origin main and then just go ahead and click this and fetch origin here and that should recsynchronize everything here. When you go to your graph, there we go. You can see that uh we have added the database in the previous one and in this one we added the authentication setup and everything regarding authentication.
1:09:46 Let me just close package lock so you can see the actual uh code like our session and our form and we just merge that into main. You can of course go inside your app page to confirm that you can see the code in here. Excellent. So that's it. We just merged our code. You can always try this multiple times in case you think it's not synchronized for whatever reason. And that's it. Let's go ahead and mark this as completed.
1:10:09 Amazing job and see you in the next chapter. In this chapter, we're going to develop the UI for our authentication. This will include the AL pages, out layout, out module, and finally the AL views or
Get the other 14 chapters, the exam and your certificate for LinkedIn, plus all 700+ AI courses.