This content is a comprehensive tutorial on building a B2B multi-tenant project management system called "Teams" using Node.js, MongoDB, and React. It covers backend API development, database setup, authentication, error handling, model creation, and frontend integration.
Mind Map
Click to expand
Click to explore the full interactive mind map • Zoom, pan, and navigate
in this video you will build teams a B2B multi teny project management system using no JS mongodb
and real you will create a production ready application pack with features like Google
sign multiple work Spaces Project tax management R and permission team invite pation filters and more
but that's not all you will also integrate this powerful API into your react app by the end of
this video and here is the exciting part we've created a written version for this course that
goes beyond the video covering asant exclusive content and everything you need to master this
project at your own pce link will be in the description so don't forget to like share
subscribe and turn on notification for amazing content like this now let's dive into the demo
of teams business owner can create an account or log if they already have an account using
Google signin the owner is then navigated to the dashboard page where it sees the analytics
it sees all workpace all recent project tax and members of the team the owner can view the
workspace setting edit workspace or choose to delete workspace if you want the owner can see
project on the left side bar and click on the more button to see other existing project also
the owner can create new project by clicking on the plus icon on the left side bar where you can
select theog give the project in name description and then submit the owner can invite team members
to join the workpace by going to the member's page and copy the invite link which he can share to
his team members the member then visit the link which is prompted to log in or sign up once the
Member log in the member will be redirected to the invite link where the member is able
to see the join workspace button once the member join the workspace the member will be navigated
to the newly joined workspace dashboard the member does not have the permission to view
workspace setting create project or invite people to the workspace on the owner side the owner can
change members Ro to admin or member the owner or members can view all TX filter by status priority
assigned to and project the owner or member can create new tax by clicking on the new tax button
and provide the tax name description assigned to Due Date status and priority the owner can
delete Tas and also delete the project lastly the owner can switch between different workspace or
create new workspace so I have my vs code open so let's create a folder which we can call a
back end I already have it here so the next thing we going to do is to C the inside the
back end so I'm going to say CD inside back end we need to initialize mpm so I'm going to mpm any
Dy and let's press enter and this should set up mpm for us so the next thing we going to do um
is to install the packages into our package J so to install the packages I'm going to bring
in some dependency that we going to use so let me just clear the terminal first and if I clear
the time now so all of these packages will have its own version I'm going to specify so
we need to install the version I'm going to install here so we don't have the any issue
when trying to run it on our own system so I'm going to paste this here and this is mpm install
bcrypt 5.1.1 C session 2.1.0 so C session with this version of passport is required because the
latest version of passport does not work has some issue with cookie session so we have um
cost 2.85 EMV express mongus passport passport Google or 20 passport local uu ID and Zord so I
just press enter to install packages so once it install we're going to install the type for all
of these packages we specify here so let's wait for it to install so it has install completely
now let's install the type so we are going to also install typescript so let me clear this
so I'm going to just bring it in let me let me type it again mpm install save so
this is it so npm install save Dev we have the type for all of them and we have TS node Dev
which we're going to to run the server TPT server then we're going to also run like we
want to set up script to so let's install it so once we install that we're going to
initialize typescript so let's wait for it to install so types are already install completely
so we have our node module here so inside here we're going to CL clear the terminal
again and let's mpm type in it so let's set up Ty script and we should have our
TS TS config here so let's go into TS config and we going to enable to enable some things
inside here so I'm going to change this one to um 20 21 save that and inside here we're going
to set the the directory so I'm going to look here let's enable this we going to set this
to Source directory because we going to create all of our um files inside this Source directory
so the output the out directory is going to be the B folder so say out directory so let's
uncom that and let's set this let's set that save so we have this we have
stet we have this whole so the next thing we're going to do is we already set up the
the compiler options so we're going to just put some comma here and let Set include we going to
say s SLC TS and also a folder which we're going to create to handle the types then we're going
to exclude some folders here so I'm going to put in comma here and I'm going to also specify this
here so this is just to exclude node mod when trying to build test and this folder and test
if you have t so let's save that and now let's structure um of back so inside here we're going
to create SRC folder so inside the SR we're going to first of all let's create a type
which will handle type for us so I'm going to say types and we're going to also have config
folder inside the SLC so I'm going to create config then we're going to have the controllers
so going to have
middle so I'm going to create the folder called enams this will handle the in for
some of the we're going to use for the project so I'm going to just create the folder already
here and we're going to create some models so I'm going to click here and let's say inside the slrc
folder so hold our schema then inside here we're going to also create a
route and again we're going to also create the
service and we're going to create yous lastly we're going to also create the
validation then before we we're going create the last one which is called CIA
so this is we're going to use toate the database so C here so we are done with
that so the next thing we're going to do is to set up our EMV first so let's to that so
if you have watched the previous video I did on ljs you know we always set up our
EMV in a different approach so I'm going to use the same format I use in those in
that video here so inside the U we're going to before we go into U so let's create our
EMV so let's create
aemv so inside EMV also need to also create EMV example
so inside we're going to specify some envv that we're going to use so I'm going to ringing the
port a port node node EMV development we going to also have our [ __ ] URI so for now it's going to
be empty you're going to also have um session secret for the cookie session and then session
expires so this is we're going to set this to just um set it to any random value on this should be
one day just leave like this then we going to also set um our Google Google ID which for now
is going to be empty Google Secrets is going to be empty for now then Google call back URL
so this is going to be empty then for our front end origin we just going to set this to HTP local
5173 and and our font C URL which you're going to use for Google it's going to be set to local 5173
Google all call back so let's save that and inside now the next thing we're going to do
is to go and set up get EMV so so I'm going to go into my uos and let's set let's call this get EMV
TS so this file is going to help us to handle EMV and if some the values are not passed is going to
throw an error so I'm going to just paste it here so this is going to be um getting key string Thea
value which is empty then we going to get process. EMV and we going to pass in the key to get so if
the value is undefined then we check if default value is set then we return default value else
we're going to show new error environment variable key is not set and we're going to return the value
so this is a proper way to handle EMV so users or other developers we have to be enforced to
pass in the value for or default value for the EM so once we are done with that need to create
a config and this config is going to pick out the emvs using this the get EMV so inside here we're
going to Let's create a file called app. config TS so we're going to set say constant app config
this is going to be equals to andless let's create an object and we're going to just pass
the node so we're going to get the node EMV from the EMV right so we're going to pass it into the
get EMV so let's import this from YouTub and you can see that we passing the dot the node EMV and
the development so we going to do that for all of the other parts you're going to work for work with
so we have the port I set the to 5,000 but in my EMV I set it to 8,000 so you can set the as long
as there if there's no if there's no part here then it will fall back to 5,000 which is default
value then my base part which I didn't set in my EMV we fall back to API which is the base part
for all my end point the mongus we have mongus we don't have any any default here so we also
have we're also going to bring all of the other parts here from the EMV like the session secret
the Google client ID from let just said that from the EMV client ID Google call Ur front origin and
front Google call Ur So let's go into our app config and let's get the let's set the last part
here so the front we going to use that for the cost so I set the default to local so you can
see that set here so we have the front Ang go URL and this is it so once we done with that
we're going to export this and set it into to a config con constant so then we can import this
inside our project inside the index or any part of the project and we can get it like this config
Dot and you can see that we have access to all of the the app config here EMV so let's just
play that and let's save that so we are done with that so the next thing we're going to set
up is we're going to go over to index. TX so let's create index TX here and let's import so index. TX
so inside index TX so we going to first of all import EMV because the config the app config or
the EMV can't work if we didn't install because we installed EMV so EMV will help us to get the
EMV inside our application so to set that up we're going to going to insert our index. TX
and let's import it like this and now we need to also import Express so let's import Express
here so Express with the type next function request response and and the other one which
is response then we're going to also import the course and the cookie session so let's just bring
it here say pause session from Cy session then we're going to we're going to set up connect
um app to express so let's say app is equals to express and now we can see we can get a config
so let's import config from config app config and now if you over you can see the Bas part is
string it's not showing any error so let's enable and piing of Jon so we're going to say express.
Jon then we're going to so enable be asking you encoded request body so Express URL encoded and
extend it to true then we're going to Now set up the this session here so I'm going to just say
app
use session and let's just open this there give this a name name is going to be session then
we're going to give it a key and key I mean so this is going to be a config do session
secret maximum age let me add comma
here Asim age just 21 day
60 time 60 * 1,000 then we're going to say security secure so we're going
to set the key to secure one we in production so
I'm going to say m node EMV is equals to production then HTTP only to true
we're going to just say same site to LS for now not
street so the next thing we're going to do is to set up our cost so our cost matches with um
send to the font end Ur So let just that app use and we're going to open this and
let's get C origin which is going to be config frontend origin we're going to set credentials to
true so so now we're going to just create our new we're going to set up our new controller
here or route to test this so we're going to say app do get going to set it to um slash
we're going to have a request out and then next and let's just let's just with a response here
then the last thing is to set up our our listener so I'm say app the listing then
we're going to say config Port remember we set up the port to 8,000 default to 5,000 then we're
going to say server listening on Port config port in config node EMV so so now let's test
server so let one mpm so before we run the mpm1 dev we need to go into our packet and we need
to specify our script here so to run our script we are going to have to use the TX TS node so TS
node Dev so we do that I'm going to just you're going to just come into the test let me just
remove this and let's call Dev and Dev we're going to have TX Das
node just dev then this is going specify the files
and SRC SL index TX DX then we're going to write our build
so to run the build we're going to first
use typescript to compile it into the DX then we going to copy the
packet so packet addressing into the
this so this is it then then we're going to set up the start the start
script which is going to we're going to use node so run the
b/ index.js so this is how it's going to we going to run our script
here so let's run our server and see if everything is working fine so mpm one
Dev and inside here we should hopefully everything to work
okay it's saying TS not F see in there a
TX so let me see why it's having this issue here so packet Jon yeah so I think I made a
mistake supposed to be supposed to be two Das not threeory so let's save that and let's run it again
so now our server is running so we can test the to see Server listening to 8,000 in development
so we have our slash so we can just test that on our browser and just put Local Host
8,000 and let's just set this to no just 8,000 I can see AO subscribe to the channel and Sh so we
set up our our server already and we structure our project so the next thing we are going to do
is to we going to move up to our database setup so let's head over to that let's go over to set
up our [ __ ] database so I'm going to go over this screen and let's open so I already log in
so what you can do is to just search for [ __ ] db.com and you you just click on that and next
thing you'll be able to see the landing page you can click on signning to signning or you
can try if you don't have an account so I already have an account you can register here so I'm just
going to close this and let me go into so in this account I have only two project here so
the next thing to do is to create a new project so let's create a new project and we're going
to give this a name let's call this team team sync and you can give it a tag or just quickly
click on next to create a project you can set project owner to your email and let's create this
project so once you click on create project you should R to this page and you should see
you already set to team sync so let's create a Custer so I'm going to click on create Custer
and make sure to select the free version so just select the free and let's scroll down
we can just leave this to Cluster zero and set everything to default then let's click on create
deployment so I'm just going toly set this
so it should navigate me to this page where it say add your your IP address or and then
you can set your username and password so make sure to copy this password and you can
also copy your your username so let's click on create database user and immediately you
can just click on choose a connection so let's go over to mongod DB for FS code so you see it
is saying closer Zer is provisioning so we have to wait for it to to be done with this
so just click on done and once it St this is still loading up you can go over to um
think database access network access so here we need to add a an IP address so let's set
this to allow from anywhere this is not the best option so you can just use I'm going to
use that for this so I'm going to click that so it works so set this to anywhere and let's just
confirm this and you should see that it is set up by um the IP address for for every location
for every every IP address so let me go back to my database assess let's just quickly go back to
rers so just go back to overview and let's wait for for it to set up completely so our cluster
is done so the next thing we're going to do is to connect to our cluster so I'm going to click
connect and let's mongod DB let's copy this mongodb for vs code so copy this and let's go
over to our code and let's paste it inside our code I'm going to go over and let me go into
my EMV inside the [ __ ] U so let's just here and make sure to you can set this to database name so
I'm going to call this teb then let's make sure to replace this with our password which we copy
so I'm going to replace that with the passw here and our mongus U is completely connect completely
set up so what we're going to do is to connect to our database so so make sure to save this
and let's go into um config let's create go into our config and
let's create create my database. config so I'm going say database
configs and inside here we're going to just connect to mongus so we set mongus and let's
get a config up config and let's create a function connect database which is async
and we have cach that await amongus connect and let's get our mongus Ur from config then
we can just console this to log this out to connected to [ __ ] database and if not we
just console error and exist so let's just save this and Export to default so once we done that
we going to go over to our index. TX and we're going to call it inside right there so let me
close this my terminal and we're going to do that below let's say after this so say await
connect connect database so connect
database and make sure to import that yeah so once that is done you can just look at our
code and you should see let let me stop this and run this again and hopefully it should connect
to our database so let's wait for it to so run yeah so we can see connected to [ __ ] database
so that's it so the next thing we going to do now is to work on the error handling and async
Handler so let's head over to that so let's set up the error Handler so the error Handler
is going to help us catch all errors on the app project so to handle error handle we're going to
come below all the middle here that above the app the listing then we're going to type in
app.use we're going to pass in err Handler so we've not created this yet so how we're going
to do that we're going to create a middle where you can handle all errors Now app so let's let's
go over to middleware and let's create a let's go to middle and let's we're going to create a
file called error Handler middleware so let's just do that here I'm going to create error
middleware TX we just put um hand layer
there something like that then inside here we're going to quickly just say export
Constance error
Handler so this is going to be um let me just close this you're going to set
a type to error Handler from error request Handler from um Express so let's just pass in
error request response and
next and just say to
any yeah let's just yeah so yeah we're going to set response we're going to return response do
status status we're going to set that to 500 that
internal server error we're going to say Jon which you're going to set a
message Ser error you can just say [Music]
error Rec it
unknown then
ER yeah so let's go ahead and import that inside the index. TX so I'm going to import this from
the middleware and we should see that the error Handler is set up now so the next thing we going
to so we also forgot to set the error this is going to be message so if there's no error
message to Jo or non error meage so we also we can also handle um other type of scratch other
errors here like the syntax error if the Json data is not um passed correctly so like this
we can say error instance in that error I will say 400 invalid J for please check
your request body so let's Also let's also console the parts so
we can log out we can log out the part here so I just put constant console do
log and let just set error
Cod on
Parts can set the part
here so let's change
this this to
this then let's just set request that part
now we can return set the error so we can also log out this and see it's terminal so we've been able
to set all type of error like the syntax and also if any error that is not catch here we fall back
to internal server error so notice that writing status code like this it's not actually the best
approach to use and this is the same Buton I used in my previous video so we have to set
up an HTTP config where we display we show all of the uh tus code in a hom readable format so
inside our config we're going to create a file which we going to call HTTP config so I'm just
going to say HTTP doc config TS so inside here I'm going to just write our constant
HTTP config and this is going to be equals to we're going to return an object and here we're
going to just say okay which is going to be a 200 um status quo so it's not much to write that you
can just copy that from the GitHub so I'm going to just that and paste it here and we can see
that we see 200 created 21 accepted and other um other status code here so we need to also set it
like this assign it to a constant so now we can also do it like this you can do status and you
can get the hom readable status here so we need to also um set the type for the status code so
I'm going to just export type HTTP HT pay status we're going to call it code this is going to be
equals to um type of HTTP sorry it's going to be HTTP status we're going to set the key so
make sure to just grab this in bracket and let's just set KY K of type of HTP status here so we
have the HP um status and we have the the HT scol type just set this to type here yeah this is okay
so now let's copy this and let's go and replace let's go over to replace that just go over to
the error Handler middleware and let's replace this so HTP status so import that from config
and um this is going to be um 400 is bad request and 500 is internal server error so so this is it
so we should go over to our indexx and let's also change this to http so let's import this and let's
say this to okay 200 so if it test the end point you should correctly so if you run this everything
still works well we can test that on Postman so I have my Postman already open here so let's it load
completely so I'm just going to open this and let me just P this locals and let just
press we should see 200 okay yeah so it's working it's working fine so the next thing we are going
to do is to work on the async Handler so to handle async to to set up our asnc Handler
is so to set up asyn Handler ASN Handler is a function that wraps asnc controller so it
wraps this controller or route Handler to catch any error and forward it to the error Handler
to prevent unwanted or unhandled exception from crashing the server example of this
is to exle of this is if I set this to a Sync here and inside the set a function I'm going to
call I'm going to dra an error here so let me close this Stam I'm going to an error here and
if I try to call these end points let me check if the server is running once I click on send
we should see that it fail this is because it conso the arrow here and it crashes the
server so to handle this we need to wrap this in a trial crash so we need to CR then once we
WRA this we have to send the error by sending next and sending the error down to the error
Handler so if my server runs up I'm going to try to test it now and we should see the error so if
I click on send we should see internal server so the error Handler pches the error and return it
for us as 500 internal server error and you can see our message here test error so so writing
try or cat or handling this way in all of our controllers or endpoint you're going to work
it's not the best approach so the best way for us is to create a middle where that handle this we
create the Handler that handle this for us so I'm going to go into into my middle I'm going
to put it into the middleware folder you can put it anywhere you prefer so I'm going to say async
Handler
middleware TX so inside here we're going to make sure to import the express the request and
response so below I'm going to set my type my type is going to be I'm going to call this async async
controller typ and let's make a call and let's put request which is going to be set
to request we have response which is going to be set to response so let me break this down
and the last one is going to be next I'm going to set out next function so we need to set out
function which is going to return us a promise and This Promise is going to just set any
here so inside there we're going to export constant I'm going to call async
hand and this is going to be let me close this this
is going to we're going to pass the controller
and this is going to have a type of async controller sorry controller type so let me just
paste it here and it's going to also return aing controller type so let's just set our arrow and
here we're going to set async which is going to taking the request response the Quest response and
next and so I'm going to also set Arrow here and let call this so inside here we're going
to set our Tri cat here so we're going to pass stand request into the controller so
I'm going to just pass it here then we're going to catch the error pass the error to fall back to
the to be cut cut by the error Handler so once you do like this if I take copy
this error Handler and go over to index. TX so I'll go back to IND TX so let me close
this and inside here I'm going to just remove every remove the CH of catch from
here and let's remove the async and let's just wrap this this
let's wrap the entire function and let's import this from middleware so we can save this like
this so once I th this error let me check my Ser one and I try to call the same point we
should get the same thing so we got the same ER so so we've been able to use our ASN and this is
reusable to any other controller we going to create so the next thing we are going to look
at is custom error and exception so for example if I remove this through error here and let's
say for example we are we are calling our model which we don't have yet so I'm going to just do
this so we just going to say user model find we're trying to find a user let's say find one
and we're trying to get the email so this all this and all not um not it's not working yet
so let's just use it for example to demonstrate how it works so I'm going to say not user so the
default way most most of us we do is to just say return response do status 400 and we just say Jon
and then we return our error back so this is the difficult to most people
do do it but we can use a way that is better by using the we can use
the new but this will not be tied to error this will have different
exception which we can use like the not found exception internal serice
exception we can use which is of writing exception so I'm going to remove this so what
we are going to do is to go over to let's clear everything let's save this back I think the error
should I don't think this error should stop so we need to also remember to add a
in here so so we need to addn here because we using so um let's go over to our file and
let's create a file inside U inside our you and let's create app error so app error we handle
we're going to use this to handle the error um exception so we're going to create that so we're
going to export this and we going to say class app error so this is going to extend from the
error we've seen in the previous what we used to throw an error in the indexx so we're going
to extend from this and we're going to set the uh status cot so I'm going to say public status
status code which is going to come from HTTP
status code type then we have we can also Define public error
code so error code is going to be not so we've not defined error code so let's go over to um the you
know and let's define error code so this can be optional if you prefer not to use this but I'm
going to just show it in this project so inside the in we're going to create a file called error
code error code. inum docx so inside here I'm going to just copy it and paste it inside here
you can find it in the GitHub so this is just just um some error message or yeah unauthorized
access unauthorized not Al not found validation error resource not found internal server error
so this is how specify and we also set the type en code error code in type which is equals to
key of type of error code in so we can use this and just set this to as constant here so just
save this and let's go over to our app error and let's let's go over back and just copy the error
code in type and let's bring it here so this will be so let's make sure to import that from the inm
here so inside here we're going to create a Constructor so our Constructor is going to be
set to message our message is going to be string we going to say status status code this is going
to be equals to http status do inter Ser error by default then we're going to set our error
our error code let's just copy this let me remove one R
here so I'm going to just just close this
here okay let's just uh get error code let's make it optional and we're going to set it
back to the type so inside here we're going to call Super super is we're going to pass
the message here and this status code is going to be equals to status code then we
have this error code is going to be equal to error code then we're going to say error do
capture capture St TR and we're going to pass in the this and this do Constructor
yeah so this so so we are done with it so this is what we're going to use to handle the the
exception so we're going to extend from up error to create different exception for this so the
first one we're going to create is internal server exception so I'm going to just paste
it here so this is it I'm going to explain that so we have internal server exception
extend from the app error and we're going to pass in the Constructor the same thing we have
here and this will just take in the message which is intern which I set as default here and we have
the error type and we can set the error type here so we can pass the error code or it fall back
to the inom dot not code exception the internal server error then we have the HTTP internal server
error here and the message so we can also provide the HTP exception that can be used not defined
by the well we can do it like this we can specify HP S ex from app error and will pass
in the message status this will not require us to set the default or will require the user to
pass let let me set this to type yeah so this require the users to pass every so we're going
to also do for not found bad request which isus 400 not found which is status 404 so I'm going
to uh bring it down here let me bring it in so we can see it here message we can send not found
this is just defa message we're going to likely pass message to it you can remove it if you if
you don't want to pass it or we can just set it to string like this so I'm just going to leave it
like this and we say error code to the error type and this is just similar to what we have in the
internal server error but just change it to not found and this one res not found then we're going
to also have for bad request exception so this is for status 400 and this is the same thing B
request and can just change it to validation error or you can add um your own error code to it I'm
just going to leave it to this error and the last one is the unauthorized exception so we're going
to also ra that here so unauthorized exception we just pass in the message the error code this
is what user will pass in once they using it and this message HTP HTTP status unauthorized error
code error code in Access unauthorized so we are going to also go to the error Handler to catch
this error from the app error so inside the error Handler we're going to go into error Handler here
and instead of us getting this error if you look at um the if you go over to this here we look at
we having internal Ser so this error we throw from the endpoint is throwing going down to
the Ser error so if we are using the app error we will create a we create um we able to catch this
error from here if is from instance of app error they will call it passing the message passing the
status and pass ing the error code so let's do that here so inside here I'm just going to you
can just get this here paste it here and we just going to say error instance of app error so make
sure to import that and if if the error is from app error then we can just simply sayon status so
this is the status code will be dynamic you can see status code and the message will be dynamic
the error code will be dynamic so once I save this if I go over to my index. CX and I do the
same thing here so let me let me dra an error here using the new let's call this P request P
request exception so if you look at say we have message error code message and error code so
I'm just going to put in error code is option I'm going to put only message I'm going to say
this is a bad request so let's try and test it out on Postman so I'm going to try and run
this so make sure the server is running and then let me click on it so if I click on this
we should see we can see this a bad request and we can see validation error so you can
also change this from here from validation eror to error error in do can change this to
uh we can just give it to anything here like invalid token something like that and if you
send it we you see invalid invalid Tok here so this is how to set up custom errors and to
also handle the exception in so let's move over to setting up our mongus models so let's create our
models so I'm going to go over to our model folder here so I'm going to close
this let me clear everything here let's go to back endc and let's go into our model
so the first model we're going to create is a user model so I'm going to say user
modelx so inside the user model we are going to create the document going to
create the type so the schammer type so I'm going to say export interface
we're going to call this user document and this is going to extend from the document
which you're going to import so make sure to import that from mongos so I'm going to just
import that here we can see we've import Mong document from mongos here so let's
just call this we're going to have our name which is to string email is set to
string password so since we're using Google um assign in sign up password is going to be
optional so we're going to profile
picture picture is going to be string or no so we're going to say it's active
it's going to be bullan last login this going to be late
or no you're going to have or created that this is going to be date updated
that it's going to be date then inside here we're going to have um we're going to set our current
workspace so we've not created a workspace model which we going to do later on so let's just set
this is going to be set to mongus type object ID or no then we're going to create a function for
we can create a method in inside the user model the user model yeah to handle compare password
and also to Omit password so I'm going to just P that you say compare password this is going to be
value to pass the string and it's going to return a buo a promise of then for the omit password the
omit password is a method that we just we can set user. omit password to remove the password
so this is just the type we're going to set omit here and we're going to set user user documents
and pass the password Val the password key here so let's create the schema here so I'm going say
constant user schema and schema is going to be equals to new schema and new schema we're going
to set the type to to to user documents and let's just create the let's create the there so inside
here we're going to specify the name which is typ string require for uh Stream True typ string
required true unique true you can set it to lower case here and you can you can also set this to if
you set false it will not return time you call to fetch the datas I'm going to say true because
we're going to use it and we're going to also set the login and the the last login and the profile
picture so I'm going to say profile picture orang workspace we're going to set it to type
Mong schema type object ID reference workspace so we've not cre a workspace model which we're
going to do that so it's active true then last log dat default now so let's make sure to set
time St here so time St is true so mongos we set our time for the updated ad and created
that so here we're going to also we're going to set up time we are saving this data into
the user model we are going to hatch this password so let's say user schema do pre-
saave we going to say pre so and here is going to be save so this
is going to be an ASN function we're going to say
function let's pass next so if this dot modifi is modified and let's pass in the key we say
password we are going to say if then if this do
password we are going to Hash this password so this password is going to be equals to
always the hash value so we're going to create that in a minute so let's just say
hash password and let's pass in this password here so this will handle the
this is what we're going to use to handle the password so we are going to create the
hash password yeah so let's just so let's go into um ins YouTu and let's create a file called bcrypt
here so bcrypt TS so inside the bcrypt we're going
to just import that so let me just import import bcrypt
one bre here so we're going to create the function here to Hash the password here so say hash pass
has value async value string s rounded s number to 10 the defa to 10 and we're going to say B crypt
the value and set the S here also we're going to also do to compare this is when we want to log in
the user we have to compare the password so I'm going to just said the compare value is going to
be value and we're going to pass the hash value then we're going to compare the value with the
hash value so let's just save this so make sure to this and just save this here and let's go back
to us model and make sure to import I mean yeah us model let's make sure to import the ash value
so we're going to also create a method to going to create a method now to handle the oh we forgot to
pass in the next here we didn't use so so we're going to pass in the next here and let's just
save this like this so let's say user user schema method this is going to be method
omit
password so password is going to be equal to function and we're going to just set this to H
it going say to H it here the same type with here let me just copy this like this and let's paste
it here and let's just put this function here so inside here we're going to say constant user
object so we're going to get the user object of this do to object
and we're going to delete the password here from the object so user object password and let's
return the user object and the error should stop so we are done with this so the last one other
method we're going to do is the compare password so the compare password is the same method compare
password async we passing the value string then we can just up this remember that the hash password
is already stored in the database through this pre save here so we're going to just pass in the
user the user have to pass in the the password and we pass it into the compare value then we
also pass in the hash the hash password and this is it so lastly we just going to cons here and
set um user model into the mongos model set the user documents the user which is the name
here which to store in database and this is the user schema user schema and let's we're going to
export default user model so we are done with the user model so make sure to just write exactly the
same thing so the next model we're going to look at is the account model so since we are storing
we are signing up with Google we are going to be stor most of the data into the account the
provider id and the provider so inside the inside the user model we're going to create account model
here so account model.
CS so let's close this and inside here we're going to also import
the documents and schema let's also export interface we're call this account document
and extend this from document you're going to say provider so we going to specify the
type the in type for provider so we're going to create um the provider type in so so that
to make sure we pass in exactly any value we passing must match this type so we can
be our code can be clean and um and organiz so let's go into app U let's go into enom and
let's create that here so I'm going to create in I'm going to in let's create
account dot we can call this
provider do inom account sorry accounts D
INX so can just simply export constant let's say provider you know and this is going to just be
equals to uh let me close this so we're going to just call Google you can call different type
of Provider we can have Google guub Facebook and last one we must put email since we're going to
use traditional way toate user using the email and let's also set the type for this so I'm just going
to set the type export type provider in type a key type key of type of and the provider so
let's just copy this provider and make sure to set this like this make sure email must Bey this two
is not important we're going to focus on Google and email let's save this and let's go over to
account model and let's set this here so make sure to import the provider in type and we're going to
also provide the provider id here so the provider id we are going to spef is going to store the um
it's going to store the email if we are using the default email ID the default email provider
we're going to store the email here because it's going to be unique we can also store we're going
to store the Google ID Facebook ID so all of will be be first set as the provider id because
provider id is going to be unique so let's set the user ID here so user ID is going to be mongus
types object ID here so we can just set if we are using refresh token you can use refresh
token here but we're not going to use refresh token so refresh token be stored in the uh
can be stored in the in the account or you can store it in the cookie so I'm going to just say
created dates created ads to so just created that so now let's create the schema so let's
export account schema it's going to be equals to new schema and let's set this to the account
document and let's just SC this and let's open this here so let's no let's say constant not um
export yeah so it will stop the error so let's get the user ID here so the user ID is going
to reference the user and this is going to be required to true then we can also set the
provider and this provider is going to we're going to get it from the provider in which is
specify here so to do that we're going to just set it here say provider typ string in is going
to be object value of value of provider in and this is going to be required then we can set
the provider id this is going to be typ string and require true with unique true then we can
just set the other values which we're not going to use just refresh token token expire so inside
here we're going to just say time time stamp to true to set the dates for us and lastly we
can delete the refresh to delete any exclude any information you don't want to come out from to
the response so can do like Jon to Jon and this will just say transform we can specify doc red
and we can delete any you can say Red Dot and if you open you can delete any of this I remove any
of this from the response here so I'm just going to say refresh let's just put refresh token here
so anything you can move anyone I'm just going to set it like this so I'm going to export this
here so constant account model so model mongus model account documents account and account
schema so so that is it here and they set default account model so that is it so the
next one we're going to look at we're going to look at the workspace model so let's go over
to our file let's create workspace model so I'm going to create workspace here model. TX so we
going to also import this here let's import the schemers from mongos and we're going to
just where typee export interface work workspace document extend from documents
we're going to have the name of the workspace description of the workspace and we're going to
have owner the owner is going to be the user who created the workspace so we're
going to set that to the ID and we're going to also have an invite code for
all a generated invite code for all of the the workspace created so created as string updated
at to string so let's say constant workspace
schema this is going to be close to New
schema we're going to set this to workspace document and let's just open this object we're
going to set the name the name of the workspace is required the description is not required it's
optional then the owner is going to be required this is going to reference the the user model
you can say reference to the user model the workpace Creator and this is going to be set
to require true so now the last one is the invite the invite code which is going to be of type typ
string then we're going to set this toire true unique so to set this so we need to
set default which once you will create the the mod the workspace this um invite code
will be generated for us so we can set that to default and this default will be will be
set by function which will generate the invite code for I'm going to say generate invite code
so let's go over to Let's create a file F that we can call this function and we use and use
it here so let's go into our YouTube and let's create let's create a file so let's go to our
you and let me create a file called U so uu id. CX we have all of our generated code here so I'm
just going to import that from uu ID here and this will just have our invite code here so V4
as from uu id4 so we're going to here so this is going to be Genera invite code function U V4
which is coming from is from the V4 here going to replace the U ID with each of the C CS have
so we're going to replace the dash MC and reduce the equally the character from the
the u u ID which is going to be return to us so the invite code is going to be a limit of
eight characters here so let's go into our um workspace model and let's import this
here and let's also set let's quickly set our time stamp
to true and we are going to create a model in case we want to be generate this invite
code we can just simply create a model here a method here I'm going to say workspace schema
method methods reset you can reset the invite the invite code and this is going to be function
and this function is going to say this do invite code and we're going to call this generate again
us said the new generate invite inside to the invite code and now let's just quickly let's
go off export this schema here so workspace model model model mongos do model and workspace document
with workspace and passing this workspace schema so we're going to export our workspace model so
we are done with the workspace model the next thing we going to work on let's go ahead and
work on the project model so inside here we're going to make close this let's create the project
modelx so let's make sure to Let's also here we're going to import the mongos the
documents schema from mongus and let to export interface project
document extend from document so make sure to just remove the S here I'm going to have
name do string we're going to also have um we're going to have the name we're going to have the
description which is optional for the project we're going to haveo we going to um have the
the workspace because each project to be tied to a workspace and we're going to have who created this
project so we're going to have workspace mongus type object ID we're going to have created by
specify the object ID created as and the updated as so we're going to have constant schema we're
going to pass in the we going to pass the project documents here to the schema so here we're going
to have the name the name here so this going to we're going to have in the name so the name
is going to be string required and trim through we're going to have string and this is going to
be F because we have a default of this so this is um stacked you can just that on your emoji
can find this emoji and just paste it here any Emoji can be the default for each project and I'm
going to set this to default I mean description toed Force then we're going to set the workspace
the workspace to reference the workspace so this is going to reference the workspace this
is a workspace ID here and we're going to also the created by the created by is going to is
going to have to reference the user model here so let's just set the time [Music] stamp to true
and let's export the model here so I'm going to just say project model Mong model project
document we passing the project which stored in our [ __ ] Mong mongodb so we going to have
project schema and Export default to um project model so this is everything here so we are done
with this so the next model we're going to work on is the tax model so the tax model is going to
kind of peig because um it has some other things required for tax here so we're going to say tax
modelx so I you going to import the schema and the
mongos from necess for mongos here we going to set export interface tax
documents extend from document comments so yeah each of these tasks we have a task code
and this task code is going to be set to string then we're going to each tax is going to have a
title then TX will have a description or no so it's optional a tax will be referen we have a
reference of the project ID so it's start to a project ID also to your workspace so we're going
to also set the workspace set it to Works to ID to to reference the workspace then the tax is going
to have some inm here which is going to be first of all is a status here you're going to also have
priority and we're going to also have I sign okay it's just this um status
and priority for now then we're going to also have assign to so assign to is
who the tax is going to be assigned to it's going to reference the user and it can be know by
default then we're going to also have who created this tax it's going to be here then we can set due
date for this due date is going to be TI to date or no dat or no then let's just put our cre and so
let's just fix this status so the status is going to be an enum and this is we're going to set this
to tax status in type so let's go over and create tax inom inside the enom so I'm going to go into
my inom and let's just say tax inom CX so for the tax we have for the tax we have um the backlog the
too and the um in progress in review and done so this is it backlog to do in progress in review and
done then why for the priority we have um we have low medium high yeah we're going to also set the
types for both of them here we can see export type tax inam type which is going to be the tax status
inam here and also the type for the priority so we're going to use this inside our inside the
tax model so let's go over into our tax model let's make sure to import this and
let's set this like this we type let's make sure to import this so we are done with setting up the
CL document yeah so let's create the tax let's create the um schema so I'm going to say tax
schema it's going to be equal to new
schema we going to pass in the tax
document unless so for the task code let me stop this so let's get a task code so the task code
we're going to be we going to set a function that will generate this code for us so let's set it to
type first string and this is going to be unique to true so we're going to have let's put AA here
default so we're going to create a fun this is going to be called generate tax code for us so
let's go over to our U ID and let's let's create this here so inside the U ID we are going to we
are going to create a sport function here so let's just bring it here so this going to be generate TX
code tax we're going to give it a prefix of tax ID four we can move the dashes and we set it to three
you can increase the length of the character or increase the maximum value of the character from 3
to four so I'm going to say to three so but we're going to set tax to the beginning of everything
so let's go over to our tax model and let's import this from U ID so we're going to also set
the title and description here so string required trim through default defa is now we can just set
this to Tri true and default is now we're going to reference our project and then workspace here
so we're going to say schema type Pro ID reference project require true is also um for the workspace
too then for the status the status we're going to the status this is going to be of type
string and we're going to have in here so inam is going to be object the value vales I'm going
to say tax status in and we're going to just set our default default is going to be tax status in
so that is it we're going to also set for priority here default is going to be let's import this defa
is going to be medium and we're going to also set for assign to and also created so assign is user
to be assigned to but the default is going to be no for now yeah so reference and um created by so
we can just set our due date here and we're going to just set default to now so let's um add our
let's add the the um time stop and let's export this let's export this model in tax model mongus
model tax documents and we're going to just set this to tax and we going to pass in our TX schema
yeah so this is it so we are done with the tax so we're going to work on the
members model so members of the workspace so let's just go over and create the model to
handle the members here so I'm going to just click on this and let's say member
modelx so as you're going to import
this so we're going to also uh we're going to export so let's just do export interface member
document extend document so for now we're going to just set this to now because we now let's
just unom commen this for now we're going to um do once we are done with the r we're going to
just specify the RO document here so let's just export let's just say constant sorry constant
member member schema this is going to be equal to new
schema we are going to just say member documents let's just let's open this
objects and we're going to reference first of all we're going to reference the U
the user ID so the user that a member to reference the user here let me just bring it here then we're
going to um reference the rule which we've not created yet but we're going to just reference
that
so so we can just comment this for now here but we're going to reference the row
then we're going to set our join at so where when the user joins
we're going to set default to date now then we're going to set our time stamp
here so let's set our time stamp to true and let's export this
model so we we have member model mongos model member document members and we're going to
pass in Our member schem so let's just set this like this and let's export to default
members model so everything is okay let's save this and let's go over to work on our
rules and permission model so we're going to have rules Das [Music] permission model
TX uh so let me delete this
[Music]
so let me create it again rul Das
permission
modelx yeah so inside here we're going to you're going to um import IM mongos then we're going
to say we're going to say export interface Ro document so this is a ro document extend from
documents we're going to have our name so now the to handle row rows permission in our project we
have to set the row type and we also need to set the permission type so to do that we're
going to create an inm first which we're going to use to handle the we're going to use to set
the rules and the permission type so what we're going to do is to go over to our enum and let's
create the enom that has a all the rows and all the permission so I'm going to call this row ints
you can call it anything you want so the first thing I want to do is to set my rule so we have
three we have the owner ad me and member and we're going to set the type here so this type can be
owner admin member or you can add more to guest or anyone you want like this so the road type
is going to be key off typ off and this is going set now we have the permission so to do constant.
permission your permission is going to be
as constant here so you can simply do any way you want for the permission but I'm going to just list
out some things here you can get this from the um giop URL so say create workspace let me split this
out create workspace delete workspace edit workspace manage workspace we have
ADD member change member row remove member we have create project edit project project
we have create TX edit tax delete tax and we have view all so this view all can be simply um
hand it because we need to we can also write this here we can call this view view uncore
projects you can do like this but I just want to set it to VI because
everybody will view this everybody will view both member both admin both owner
view so there's no points for me setting it like this separately so set it just set it
one here call it view all or view only anyone you want you can also make it better by setting
owner um say is workspace and workspace to have a list of um
creat updates or you can call this to edit delete and we can also have
view so you can decide to follow this approach if you want than this one but I just want to make it
simple for us to understand so I'm going to just remove this and let's go on with this pattern so
we set the missions so now we need to let's get the type four it here so export type permission
type and say this to permission so we can go over to our model and let's bring in our road type
here and let's set
permission so permission we're going to have each each owner each of these me
each of this row we have a list of permission which we're going to so let's just set this
aray we're going to work on that now so let's say array of um array of um permission let's
get permission type so let's just go over and create this by assigning each of the
row their permission so we can do that inside the U here so let's just create rowes Das permission
TX so now inside here we're going to import all of the we going to import
everything from here including the type and the permissions and rules here going to import the
rules this Ro the type the permission and the permission type here so now now let's do export
constant see rules foration this is going to be say the type of
record to call Key
of type of row and array
you can just simply set this to ro
type you can say type here and we can
have of permission
type yeah so let's just open this so now we're going to set [Music] owner so owner
own is going to have um permission
dot sorry [Music]
permissions
do okay let me check this permission is sports
here oh sorry guys I think I made a mistake here this should be equals
to equals to
unless this is not
close so I think it should be like this
so let me just say like this permission yeah so we're going to have create
workspace so we can do for all of so owner can do almost all can do all of this by say
permission create permission permission edit delete manage for space setting add
member change me remove member you can also create project edit delete
project create tax and delete tax and also all of these so we also have the
admin so for the admin admin we have uh just L we have ADD members for
can't change can um can change member row but I think they can remove member
we can set that to remove member we can have create project Elite project
Elite project create tax Elite Tax El tax and they can manage workspace well let's
just remove the remove member for now like this so I'm just going to um close all of
them then the last one is member member can only view can only view view create T and edit TS
or can delete tax so let's just save this you can also add delete tax if
members can create so there's no point for to delete you can also allow them to
delete the TA so the next thing we're going to do now is to go over to our
Ro model r model let's complete that here so I'm going to so let's constant
r r
schema it's going to be new schema let just set the documents documents
here and we're going to set the name so the name
is going to be of type string and we're going to have in here objects
the values we going to have our rules so it must match this F it must match the it must match this
rules which we have owner admin and then member so this is going to convert that object to a list
so if you look at it here you can see that is a list here so say require true and unique to true
so we can have um the same real name in in the database so we're going to also have a permission
sorry
permissions this going to be a type of a list of
string then we're going to set the inam to
the in is going to be [Music]
permissions so we need to make sure to import this permission import this here make sure to import it
from the make sure it should be in this and now we set this to [Music] requ and let's set default
so default we're going to set to a function and it's going to take in this this uh Ro
document going to just
return going to return rules [Music]
permission permission let me just drag this down here and this we just passing this
name and this should stop the error so let's also set a time stamp for
this and let's export the the RO model so let's go over back to so I think everything is complete
here let's go over to our members and let's um enable the members model and let's enable the
road documents now so let me just import this for R and permission model and let's enable this so
I think we are we are done with the members model so let's go over to so we're going to
populate before we try to add user so we're going to have to populate the database with
R and permission here so we need populate the the um the r and permission model with this inside our
[ __ ] Deb so let's go and so in order for us to populate the database with our R and permission or
initial data this is also referred to our seeding so we in order to perform seeding we need to run
a C file so we need to create a file inside our C folder which we should we will run that
this data we have into our database so you can also use your sample data initial data or any
form of data but in this part we need to populate the rules and permission into the database so
before we can create user and reference the ID in the members model remember we are specifying the
ID here in the members model so we need this thing to exist in the database so in order to
do that we're going to go into our c folder and let's create a r let's create a row row.
CA CX so inside here we're going to create a function I'm going to
say an function we to call it seed R let me seed R this is going to be
async and we're going to return return this so let's let's make a log here so
we can track this so since we're going to look through these rules and permission in our utus
here we're going to look through all this and populates the owner the admin and the members
into the r and permission model you can see we have to pass the permission and the name
of the ru so we we going to let's put a TR C so we're going to use uh you can you can do it
by looking through the rul and permission here that will be the right that's what we're going
to do but I want to also use transaction so a transaction IM mongus ensures that multiple
actions on the database are done together if one fails all changes and pel to keep the data safe
and consistent so I'm going to use that to on this sitting process so what we're going to do
inside the Tri C here we going to do that we're going to call constant session this
is going to be AWA mongus so I'm going to import mongus and we're going to call start
session so start session you can also search for for it here if you want to
learn more about it you can call your SE for
mongus mongos [Music] transaction and you can see you can read more
about [ __ ] transaction here you can see um the documentation specify what it is
so to populate multiple operation and you can also search for for
mongos mongos mongod DB
sing so this will bring out the this will give us um I think we can see
some example here there's no specific recomendation for that it's just I think
it's for mongodb you can look at it here I think yeah so you can just check that up
let's continue from we stop so to do the process for the transaction we're
going to say await go start session and we're going to use this session here to start the
transaction so before we run this setting we're not going to C the C file is not
attached to index. or run in this app listen so we're going to run this file independently
so we need to connect our database here so I'm going to import our connect database which we
have done inside our database. config make sure to import that then I'm going to first
of all once we are trying to populate the database we need to delete the existing data
there so I'm going to make a log here unless let's delete the r model later so we're going
to say delete a wa Ro model and delete many where we're going to pass in the session here
so everything are chain together so Ro model delet many to clear our database first then
we're going to have to Loop so let's say four Loop constant row name in row permission row
permission so we can say constant row is equals to R
name we can just say to ask key of then type of row [Music] permissions yeah row permissions
so we can see permissions then inside here we're going to also set the perm per here we're going to
say permissions is going to be equals to the row permissions which we have there and we're going
to pass in the row so we've gotten the name of the row we're going to pass into the permission to get
the to get this if we go over to our permission then we can get the permission from this so let
me go back to my and then we need to check you can do that so you can skip that but we need to check
check if the row already exist but we already deleting everything so this can be skipped so
I'm going to add it here so we're going to say existing row existing I always R find so we're
going to find one to find one the name pass in the row and since you remember row is unique so we're
going to pass in session to this remember we're passing we're connecting this to the transaction
so everything is been changed together so once we get the once we got the existing rle we say
if not if not existing rule we are going to say constant new new row is equals to new row
model then just open this we going to pass in the name do row
so we're going to pass in the row row is any of this we're going to pass in the permissions and
the passing the permission then we're going to just save this data so I'm going to just paste
it here and remember we are to save this we're going to pass in the session to so we're going
to save the new row save and pass the session make sure you're passing the session session
here and Session One you try to find and pass the session here when you try to save so we're
going to just lock that to confirm that this save so row added to it the permission so else if this
already exists so we just log this out to and say R already exists so we are done with this
the last thing we going to do is to commit this transaction so we're going to say await
commit transaction and then we're going to just let me just also log this out and say transaction
committed then we're going to also the last thing we're going to is to end the transaction
so transtion is so we're going to say end session and log this and just save session ended and then
we can just write Lo this below it and say seeing completed successfully so we can just
capture this error and say error during seeding and passing the error so we are done with our C
file so now the next thing to do is to call this um to call this function all this function now
so make sure everything is similar so we don't make any mistake to avoid error so let's one the
file so we're going to say C rules we're going to call this function and catch any error from
this so I'm just going to say if there's an error we just ch there a console error error
running script and you specify the error so we can do that so we are done with this now
what we need to do is to run the file so before we go the file let's go back to our package we
going to have to set it inside our package adj here we going to set the the uh script for it so
I'm going to go I set this you can set it set it up here let me set it at the top you can call it
seed or you can call it anything let me just put comma and here we're going to say TX D node
then we're going to specify the five parts
s SL row dot make sure this is correct with the file s CS so now we can run MPN run so
let's try and run that now so I'm going to let's connect this to we you can create a new
separate terminal to run that so I'm going to say mpm run SE and let's press enter and let's
see let's see wait for it to run so think we having some error so let me just cancel this
here let me close this first and let's see it say new erment variable key not
set so I forgot we need to import the uh we forgot to get the EMV so I'm going to go into
index. TX and let's copy this remember this config is been passed inside the
connect if you remember inside the connect database we are using config the [ __ ] URI
and this file is been run on its own so we need to import this up here so I'm going to just import
this here so this will solve the problem of not able to find the [ __ ] URI so let's find it
again and hopefully it should
work so seed rules started we should say the next one should be existing existing data so
you can see R added add and end soeding complete successfully so we can check this in our database
so I'm just going to go into my mongos here mongodb and let me connect this so let me connect
quickly connect this to my MOS so I'm going to copy this let me go to let me connect this
here so
connect [Music] connecting and yeah it's connected so I can go into mongod DB and this is it so I'm
just going to drag this down going into my database and we can see row then you can see
document three documents we can see owner and the permissions we de created it we can see the
admin added we can see the members added so this is great so we've been able toate our mongod DB
database with r and the r and permission so now we are going to move over to work on our end point
endpoint so so let's go over to work on that let's create our Google o endpoint
so to handle that we're going to be using passport o to handle if you go over to your
pack you see passport Google o so this is what we're going to use to handle Google o
Endo in our project so inside our config we're going to create um we're going to
create a file yeah so I'm going to just create a file here so just go here and let's say
passport config CS so inside passport. comy we're going to import passport
and we're going to import Express here so I'm going to just import
that let me close this here so we're going to say passport let's create
use and inside here we're going to set our strategy so this is going to be a Google
strategy so we're going to just set this like this say strategy as Google strategy from the
passport Google or strategy so we're going to say new Google um strategy so inside we going
to have some things to put inside some arguments you're going to have client ID and the client
ID we're going to get that from config dot so let's let me config import config from our app
config um Google ID so let me client ID so we're going to have client secret un
confy the Cent secret we going to have call back URL so this is going to be an end point
which we going to create later over then we can specify the scope the scope can be
profile profile and the user email so once we do that we can also pass request call back to
true if you want to set anything to the request so once you're done with that we need to we need
to and this should stop it error so let me just do like this and the
error should stop so yeah we're going to we can get the request here if you
pass pass request to call back then you can get the request here and set it to
request and request will come from our Express here and we can set access token this is going to
come from Google refresh [Music] token so we're not going to make use of all this token what we
need here is the profile so we're going to get the profile here and we can just pass in done which is
required here for all back so inside here we're going to sear for cash and this we're going to
structure the profile so I'm say constant structure the profile and we're going to get
profile doore Json let's call that let's not call it yeah this and then we can get the [Music] email
we can get the sub so sub is going to going to call this Google ID I'm going to get the
picture which we can save so I'm going to make sure that the Google ID exist because we need
remember we set um the provider id to be unique and required so I want to make sure that this is
required so I'm going to set a mod found if if it's not if it's not found so we just cancel the
the end the end the process so I'm going to make sure we also conso that let's see if it will come
you can also conso the profile if you want
to yeah so let me I can move this up to so the next thing we're going to do is
to once we've got the email Google ID and the picture we need to create a service
that will handle this so I'll just say constant and I'm going to call this um a
is called is log but this will handle login on great um account you can call this like this
for Google and inside here we're going to pass in we're going to pass in the provider
the provider is going to be we're going to get our provider in now remember this is
coming has the Google G up and we're going to specify this is for Google so we using Google
we not using Facebook we're not using this is for Google we're going toy the display
name so this is going to be profile display name that is the usern name we going to set
a provider id here remember this is going to be Google provider
id remember that notice that we didn't get name from here so we got directly
from the profile display name so set the picture so picture is going to be from the
picture then lastly the email is going to set email then we're going to just get the
user from it and going to pass it down to the done um call back here and if this has
any error we're going to just set error I'm going to set this to
false so that is it so let's go over to our um or and create this all service and
let's create our first service here so I'm going to going to this place
and let's create the let's create the service inside our or so say. service.ts
so let's export um let's export constants we're going to pass this and let's get a
sync and let just say
data and we can just [Music] the this here the provider display name profile
picture picture and email yeah so let's just say let just this like
this yeah so I've gotten it right so we can also remove this from undefined yeah so but we're going
actually going to check that first before we do anything so I'm going to D structure everything
and get them here so get them from the data so now since to create a user remember before once
we create the user we want to immediately create a workpace for the user and also add the user as
a member inside that workspace so if we go over to our models you can see that once we create a
user imediately you want to create a workspace for the user because on the client side you
want to be able to redirect the user to a place where he see the work workspace we can call that
my workspace so that is the initial workspace created by for the user once they register and
each workspace is connected to a member so if you look at the member schema we can see that it's if
you look at the member schema it start to so we even we we didn't add the so I omed this
sorry guys I omed this specifying the ID of the members the work space inside the member so we
need to reference that too so I think I made mistake here so we need to reference I don't
know why I didn't hold error we want to make sure sure that you cover this so please just go over
and put the workspace ID because we specified it in the in the member document so yeah every
workpace every member members will be connected a user a user from the user um scheme or user
model we we have we connected to a workspace so let's go back to our our service so now
to do that we are going to first of all we going to create we're going to first of all check the
email if the email already exists so so how we're going to do that we're going to say let's do try
catch here because we're not wrapping this with any a sync so I'm going to say let user since
we're using this um service for both creating the user or loog the user so we're going to say await
and we're going to say user model import that we're going to find [Music] one find one for
email and say if not
user we're going to say um if not user let's create so that means the user does not exist we
need to create a user so before we continue you'll notice that we need to do countless creating and
saving like the user model we need to create the user then we need to also create the account for
that for that user so the user will create a user get a user for the for the user we create
the account we also create a workspace and then we will create the members the member will add the
user and the workspace inside the members model so we are doing multiple actions here so what we
are going to do is to use the transaction so I'm going to use transaction here to handle this so if
any one that feel everyone rely on each other the user the account the workspace and the member will
rely on each other so user can be created without adding them to a member and them to the workspace
because we creating the workspace immediately after registering the user so I'm going to use
the transaction so to do that we're going to use our session here and say session a with [ __ ]
start session what we use in the RO when we're trying to see upate database with the rules and
permission so we're going to start the session here so I'm going to start this transaction I
mean say so I'm going to start transaction here so session start transaction started session so
here we're going to just say dot session so we want to connect everything to this transaction
want to change everything to this transtion so now if not we need to create the user so to create the
user we're going to just specify user so new user model you pass in the email displ name which is
the name the profile picture which is picture or we said no then once we are done with that
we can save the user so we can get the user ID so the next step is to create so this should be
user the next step is to create the account so let me say constant [Music] account this
is going to be C to new account mod model and let's passing the user ID first so make sure
to Let's import this first from account let's the user ID the user ID is going
to be user doore ID so we're going to set the provider remember the provider here is Google
can set the provider you can also add a type to provider type to match all we pass to match with
the provider or we've already set it there's no problem for that then we have the provider
id here so once we are done with the account you have to save the account here so now the next one
we're going to do is is to create a new workpace for the new user so immediately want to create a
workspace for a user so to create that we're going to say constant workspace do new workpace model so
let me import that and let's give it a name you can give this um the to match the name of the and
say the name of the user user. name if you want but I just want to set this to just simple my
workpace you can set this question to this so what space created for
user. name here then the user ID will be set as the owner remember owner is set
to referencing the user so you're going to connect the owner of the workspace user ID
then we're going to save the workspace so now we need to get the rules we need to get the rules so
to get the rule we going to try to get the ID for that particular rle so we can say default
this is going to be set to be the owner of the owner of the workspace I me say so I'm going
to just first of all find I'm going to find the rule in my rule model so let me just import this
here from the rows AR rows permission RS permission model it say find one name the
marches rules from the en owner if you look if you go over here you can see we are pointing
to owner to much we don't want to hard code anything here say R then we set the session
here because we finding likewise what we did for the user then once we get this if for instance
we've not prop the database with the rules and permission this will an exception say owner rule
not found then this will cause issue and then our transaction will help us to handle late and
to have any issue with the any of this model f to save so if we got have gotten Ro owner R then we
can create our member so we're going to add member is equals to new member model so let's import
this let's say user ID and let's set user. ID the workspace ID is workspace doore ID
then we're going to say rule is going to be owner rule
doore ID so we gotten the owner the ID then join dat we can just say join date
to to new the new date and we can save iMed save the member so once we are done with
this remember in the user model if I go over to the user model We Set current workspace
Here We Set current workspace to the workspace ID so now we need to connect set the workspace with
my workspace which we've created to a current workspace so I'm going to set this AR and we're
going to specify this to as [ __ ] type ID so user current workspace workspace ID as mongos
type object ID then if that we need to now save the user and make sure to pass the session so
make sure to pass the session look at it clearly and pass the session so we don't have any issue
so session session session here then session here s and session here so once that is done we done
with everything we're going to just quickly go outside the the check and is going to say
going to comit and end this session
so so we're going to just say SE we're going to just let's log this out say end session then
we can catch the error and we can just um let's return the user remember we need to return return
the user so inside we're going to abort this session [Music] if any error and we're going
to end the session and lastly we're going to just show that error here and finally we can just end
the session if nothing goes wrong here we can set finally here and to end this session so
this is it this is it here so we are done with this let's go over and import this inside the
passport of config so to go into my passwort or config and let's import this login create
account if you go over to this pack you see that if the user is not the user already exist we just
Recon the user if I close this now you can see we just Recon the user directly so let's just save
this yeah so so we are done with the um we done with this here so we're going to
go over to get our client Google client ID just me so let's first of all go and
set up our route to connect this to Route so inside the route I'm going
to I'm going to create alt route here so let's create alt rout here routts
so inside here we're going
to we are going to Let's create
rout it's going to be from
Express and we going to say we're going to do a get request and get request will come from
passport authenticate I will specify the strategy which is um using Google yes so we're going to
use and we can set the scope to um profile email you can also set session to first if you don't
want passport to use session if you want to use JWT or stuff you can stop you can just set this
to First and also go to index and comment the cookie session so since I'm using session here
I'm going to just remove it so we set this so we can call this endpoint on our browser
and it will take us to Google once we set our client ID then we need to set the call back if
you go into EMV F you should see that we have Google callar URL this Google call Ur which we
going to set is going to be our Endo which we going to set so let me go back to the UT
let me go back to my rout and here we're going to create I'm to say out. getet it's
going to be get request and we're going to call this Google slash so let me put
SL here call back and here we're going to you're going to also the same we did
here we're going to remove the scope then instead
we're going to pass field if for any reason we have
field we have any field issue or anything that could goog can s Us in we have go
redirect us to this failure redirect to this so we need specify the URL so we're
going to connect this we're going to set this to our font end URL here so I'm going
to come to the top here let me a field URL this is going to be equals to let specify
config from App config dot fonted you can say fonted Google call back if you go over to EMV
you can see we specify this here Lo gole call so this is for the client side the font side so
let me go back to our rout and inside here we're going to just say let's just give it
status or F anyone so let give this is fi here so I can just set this to this
here so now we going to also create we're going to pass our controller here so we're going to call
Google login call back or Google log call back controller you can call it anything controller
anyone you prefer or Google login controller so you leave it to Google call login call so let's go
ahead and then work so before we set the uh Google log come back controller let's go over to our
package we forgot to add something here we didn't add our passport ster so I'm going to call this
passport do serialize serialize user and this will be user then going to say done then we can just
what is it done now user we can C in we can just duplicate this and call this is realiz user we're
going to just do the same thing so basically this is what we need to do here so I'm going to close
this and let's go over to to handle this so so let me let's un comment this and let's create this
inside our controller so we're going to create an out controller here so I'm going to just go
into into into our controller and let's say alt controller t s so here we're going to say export
constant and remember we need to pass AC Handler because this is going to be it's a request from
Express remember we say our [Music] response response from sess let's SC this yeah so
inside here we can just get conance so let's check if we can get the user yeah
we can get the user so it's a constant current workspace is going to be equals to request do
user do current workspace so you can see that is saying that property does not exist in user
so let's just come in this for now let's import this here we going to come back to this so let me
think this is still showing some error because we didn't return anything here so I'll just comment
this for now here let's just this and let me go over to index of TX and let's first initialize the
passport first so we need to import the config here so I'm going to just go over
to this can let's import the config and then we need to initialize passport so I'm going to just
initialize passport here say passport initialized and passport um session then below here we need
to also set the route so a app make sure we export this so we didn't export this
so let's go over and Export the out route here set to default here so I
say this to default and let me go over to my index of TX and let me just say app do
use and let's say so base part remember base part
is cutting from the config if you go into config you see base party/
API so we're going to have
slash and let's get
out so this is
it so to handle to fix the issue we have with the
Google inste of Google um call back controller let me go into
Oller so we need we can set the type here so I'm going to set type here that we take the express
here and connect user extend the user from the user document so I'm going to call this index a
TX so here we're going to say declare
Global name space
Xpress then interface user extend from user document
yeah so I we need to also set ID because this can't see ID I say to any and that is it so
let's try and see if this will work so yeah we can see that the current work space is showing
now because if you yeah we can now see the all the user yeah you can see everything
here so let me just get the current work space and let's just complete this so I'm just going to say
if if no current work
space so let's just return the user to the um field so I'm going to import this
we're going to just redir the user to the field part here so we're going to manually
already the user but if there is a current workspace that is a workspace ID we return the
user to the workspace the workspace ID the current workspace ID so response Weir config the font and
origin remember font and origin is if I go to my EMV is a client URL so I'm going to go back to
controller and we're going to juster to the workspace the current workpace
ID so let's save that and let's go to auto out let's enable this and import
this so now we've done everything we need to do so only thing left now is
to get the is to get the idid so to get a client so I think this
ISS okay let me put comma here so I think that will fix it so let's go over so let's
go over to Google console developer console to get a client ID and the um client Secrets
which we set in the passport or config here so if you go back to our EMV you see
that all all of them are are empty so we need to also set the I think we already have the the call
URL which is set to the end point here so this is just going to be you say HTTP it's going to
be local 8,000 which is what we set the part here and this is going to be the base part API or or
is what we set in the index. we set all here so let me go back to my EMV and we're going to say
Google call
back and this is what we set in the route Google call Bank so we set the the call so it's remaining
the client ID and the secret ID so let's go on and work on that so let's go ahead and get
the Google client ID and Google client secret so I move to a new tab and in this new tab I
already have my um console cloud. Google open the dashboard you can just quickly you can go over to
this console. cloud. Google link will be in the description so the first thing we going to do is
to create a project here so we are going to click at the top corner here of this and let's create a
so you can click on new project here and immediately it's going to open a new page
for us which we're going to type in our project name and also select if you have um organization
you can provide that there so I'm just going to give this let's call this team
sync okay yeah we got this so let's click on Create and we should wait for it to create
and what is done we can select and go into this project so it is complete it is is done completely
so let's select the project and the next thing we are going to do is you can see that it has
set to team syn here so what we're going to do is to let's go into our API and service
so inside the AP and service the first thing we are going to do is to is to set up our o consent
screen so let's click on that let me close this so here you have to set the user type so we're going
to set the user type to external for external user is going to use is going to use this um to sign in
with Google so I'm going to click on external and let's click on create now we need to set
up the app name we can just simply call this s Sync here and you must provide an email so
I already have my email selected you can provide logo if you want you can provide domain if you are
find this application or something like that then I'm going to to provide the same email that I use
here and make sure to click on Save and continue and this should take us to the
scope so on the scope side we're going to select add scope so we're going to click on
the add scope and we can select the user info email profile and open right so associate with
your personal info on Google I'm going to check this check this and check this
and if you're done with it just scroll down and click on update and we should
see it here so once you have selected that we can click on create mean save and
continue so we can add test user if you want but just save that and we are done so let's go over
to um credential so we're going to create our credential here so if we click on credential
the next we're going to do is to create a new cre so click on Create and select all client
ID and this select a application type to web application we can leave this to web client
like this then we can scroll down to where we have authorized reir URL then we need to
provide our call back Ur here so we need to go over to so you can copy that from the uh
EMV so I'm going to so I've past the UR local apiou so this is our Ur the API URL you can also
add on like you can add the font Ur here if you want so you can keep on adding other Ur that has
that Google can redirect to so but this is what we going to set here so once you're done with adding
the Lo 8,000 API or Google P back you can click on create so make sure everything is filled and
just click on Create and immediately we should see the all client you can see the client ID and
client so make sure to copy this and copy this so I'm just going to go over and paste it yeah
so I'm going to just clear this let me clear this and let me paste the the secret and let
me paste the the client ID so make sure this is correct so I've ped my the Google client ID the
one that has Google user content just come and the C secret so just save this and let's make
sure our terminal I'm going to cancel this end this process here and let's um run our server
so mpm run Dev and this is this should run our server and if we go over let me
c close this so let's close everything here so you can have a clean editor so let's just
go over to our route which we set here H rout and we should be able to use this now
so let's try this out let's try to go to H API Google Google so we can do that on we can do
that on our browser so let's go here let's open a new tab and let's type in HTTP and let's just put
local 8,000 API slash Google and let's press enter so I think oh yeah sorry guys we need to
put out Google and let's not htps so press enter and you should see we are redirected to chose an
account from Google and we can see the name to continue to team sync so I'm going to select my
email and once I click on continue here we can see that the user information is Ono we can see
the user information here from the profile which we conso inside the I go to passport. config if
you scroll down we notice that we conso the profile and the ID and you can see the name
emails this is without the Json but when you choose from J we can see the Google ID which
is known as the sub which should specify here the email the the name giv name the family name the
picture email and email verify this is profile then also say Google ID so Google ID is is a sub
so that is it we've been able to create the user if we go over to let's come to uh so I'm go the
and let me reload this Let me refresh this then we can see that we have the account member role
user and workspace if you click on workspace you see we have one document here and once you click
on this you can see my workspace and this is created for my by for emmanu so if you go to
user we have one user now we can see the user user is been set here great so lastly we also
have the member we can check the members to see the member and we can see that we said the ID
user ID workspace ID and the rule ID and the RO ID is the owner ID lastly we have the account if
you open the account and click on document here we can see we set the ID the user ID the provider
to Google provider id to is ID there and others so we able to create uh endpoints to create the
user so if you try to access that endpoint and you can look at it we redirect the user
to the front end Sport with workspace and the current workspace ID so if I try to access it
again if I try to access Local Host 8,000 the API Google if I click on
this and I try to select Google select the email again what will happen is it's not going to sign
up sign register the user anymore it's just going to log the user so that is how it works
that is it for Google or so the next thing we going to do is to work on the registration end
point so let's go ahead and work on that so let's work on the registration end points so
I'm going to close my terminal here and what I'm going to do is to go over to controller
and let's create our register user controller so I'm going to click on us controller let me
clse the Google login callback so let's export constant register user controller
so remember we need to set pass in async Handler and this will be async
request which is set to request and response to set to response let's call
this so to register the user if we head over to the user model remember we passing
the name email the password and um just the name email and password is required
here and provide a picture URL but this is going to be optional so we need to handle
validating the request body so we need to validate the request body so user provide
the required feed before creating the user so to handle that we going to make use of Zod
so Zod will be used to handle validation here so to do that you're going to go to
the folder which we've created before which we call validation so inside the validation I'm
going to I'm going to create a file called alt validation so let's create a file here and let's
call it alt validation. CS so here I'm going to import Zord inside here and I'm going to export
constant I'm going to call this register schema and this is going
to be thir object because our press Bo is going to be an object and we're
going to set name so since we going to be using you can set set the string here
first and we're going to use stream you're going to set minimum of um minimum of one you can set
message here if you want but I can just leave this so we set a default message for me with a
fi name so we can give a maximum of 2252 55 so we can also provide you for the email and password
but we also know we are going to later on do the validation for log so to use I'm going to WR log
here so and the login is going to require us to pass in the email and then password
so to do for the email I'm going to say email but instead of typing the
for the email I'm going to create it at top here and so we can reuse it so I'm
going to say s ort constant email schema this is going to be set do
string
stream I'm going say email you can just set
invalid email here address you can give it uh make sure to put minimum
of [Music] one so let me organize this here and we can just put maximum of
255 then we can take this email SCA and paste it here and also do it for the login to so this is
how it's going to be so lastly we're going to do for the password so we going to create a reusable
yeah schema password schema and this should be string Str andam you can have minimum of six or
minimum of five so I'm going to just put minimum of two let's say four here so I think we need to
set the password now so let's say password to password schema and also do that for login so
we've set up our validation for validation schema for the register and log so we're going to go over
to our controller so before we go back to handle the controller here to to write the um the use the
schema the validation register schema we need to also handle errors return return to us in from Zod
so I'm going to show instance that so let's just try and complete this and we can show example of
how it is before we fix find the solution to fixing getting the error response the error
from Zod handling the error from Zod so I'm going to place so say body is equals to register schema
so import reg schema from validation then we're going to P this and pass the request body so
once we pass the request body we are going to to connect going to our wait and let's create
our register service so I'm going to say user service and here we're going to pass in the
body so we are going to also return response status
http status.
created and here we're going to pass in addressing
message so message is going to be user created successfully so let's create
service inser our service um yeah so inside our service I'm going to copy the user the
register user service and let's go to the service out service and below here we're
going to close this down first we're going to export constant and let's create Ser it
async we're going to say
body so inside this register um service we are going to also we going to also get
the email pass email name and password so let's just let instead of that let me
just structure this let's just do like that body and let's set the type here
email to
string and let's set name to string
password password to string
yeah so we can just simply structure this from the body and get it so since we sign
the user it's similar to what we did for the login log or create account so
remember here if the user does not exist we have to do exactly the same thing here
so we are going to replicate this for the register service you can also use the log
service to handle that but we are not going to do that because once we creating the user we're not
going to use the we're not going to use um if we go over to account we're not going to pass in all
of these display name and pictures and provider so you can use this you can just provide the email
here you can provide the username and to but we need to save the password so there reason why I
didn't use this so but we're going to also use transaction to handle the registration
to so I'm going to copy this here session here and let's just paste it here and let's do try
catch and here we're going to first of all get existing user if the user is not found
so I'm going to just P that here and remember set session similar to what we did here we're
trying to get the user so here we're going to an error if a user email already exist we're going to
just we going to just import this here then say session session then existing user true
new um B request so email already exist then we're going to create the user model
so for the user model we going to just get the same thing here the user model
past this here but we're not go to passing any picture because we're not passing any
profile picture here so we can save that make sure to pass in the session here because we
oh we even forgot to start the transaction so I'm going to just start a transaction session
to start transaction so the next thing we going to to create a user um account so
we're going to say account this is going to reest to new account model and let's
open this so remember we're going to pass in the user ID user ID is going to be user idore
ID and we're going to set a provider and the provider now is going to be provider
inom email and our provider id is unique likewise our email so we're going to set that to
let's let's uh wait account just save session so now we need to also create
the user user workspace so also first we're going to just copy everything like this
here and let's come down here let's past this so remember to pass session into the account so for
the workspace in my workspace for the username owner user ID make sure to pass session here we
also need to find the role model that is the owner r. owner we say the session then if not owner row
not found exception then lastly we need to create the member so we need to copy this here let's come
down here and paste it so we create a member passing the user ID workspace workspace ID the
row which is owner owner row. idore ID the date then we also save the member remember we passing
session then we can set the current workspace to the current workspace which we created so so we
save that then we need to end we need to commment the transaction simply how we did here commit and
end and we just going to we can return the [Music] user if we want I'm just going to say um so below
the user just save to save the current workspace we're going to come me the transaction end this
session and here we can just pass in the user ID and I'm going to use this we can pass in user ID
that's
ID you can passing the workspace
ID so you can choose to add so just set send only pass the user so last we just
going to um AB transaction if anything if we fail to save the user create the user
so I'm going to also end the we're going to end the session to here once we catch any error and
throw that error so let's save this and we are done with the register service so we are going
to go over to work on the let's complete the let's import it inside the uh control so make
sure from the start session to session transl and start transaction user model account model session
are been passed to all of them so let's go into controller and let's import the service so we are
done with it so the next thing we're going to do is to set that route so I'm going to open my ALT
route and I'm going to set register to so let me just put register here so let's import register
user controller all right think we are done with this so let's go ahead and test the register end
point so I'm going to go over to my Postman so I'm going to open this you can see I already have
a list of um all the folder created for each of the endpoint so I'm going to say register
user so register user my base URL here which I set is local API so just know that adding the
local API you can do the same your EMV you can create I think it is here let's see yeah you
can create Global go to Global EMV and create the EMV here can add the base here so already
done that so let's try and go to API snatch start register and let's say this to post
and once we set supp post we're going to pass in the body set to wrong and we need to check
test our validation first so I'm going to make this optional I'm going to make
password optional I'm not going to pass empty I'm going to make it empty so let me [Music]
this so I think this is not so let me copy all of them and let me remove this one save so I'm
going to go into my [Music] register yeah so we have the username email and password so let me
just make um let me make the [Music] email and also the password so let's save this and let
me try and and create this user so I'm going to open my make sure my mongodb is connected
so I'm going to click on send and we should see our error handle CES this type of error
intern Ser because of Zord so Zod is string are telling us that the string must have at
least one character we have email okay this is for email this is for email this is for
so we can see that is trowing this error if you scroll up you can see more of it see Z error so
we need to be able to get the instance of sord error to be able to catch this error
modify it and return it in a cleaner way so to do that we're going to go over back to
our so inside the error Handler we are going
to we going to um so let's also do the same thing we did here so I'm going to
say if error instance of zort error so let's say sort error let's import that
we going to return so we're going to create a function to format this Zord error for us
so we're going to say where I'm going to pass in the error so let's create this this function at
the top here so I'm going to create it here so here I'm going to say format s
error response and is response here error and then result so let's import sord do s
error response so let me import response
here yeah this should stop from Express so this should stop error so inside the s
if we open our it should open our terminal and let's go back to the error we should see we have
something called the issue issues the issues so we need to Loop through that issue so to
map is so I'm going to say constant error is going to be equals to error dot ISS choose do
map ER I'm going to just object you're going to say field error do part you
can see the part here and because the part is an array so we're going to use
join going to join them by this I'm going to say
message error do message so we are done with this so now the next thing we're going to do
is to return we're going to do um sorry we going to also the same way we did return here
you're going to also return return this for validation I'm going to just return
this and we can see uh error I'm still St HP status bad request and we can see validation
fi you can also add our error code here if you want and you set this to you can say
error inm do validation you can set like this so we have message validation field error errors so
this will list the errors for us so if we try to test it again so let's check our server is
running so it's connected so let's try and test it if you click consent we should see a cleaner
way we see we have email invalid email address email string must be at least one character
and passord password must be this for so our validation error message is cleaner so let's
try and fill in this information and place this out so I'm going to just set everything
like this Jo that's the sample.com so let's try and test it so I'm going to
click on [Music] register you can see user created user created so so we are done with
the registration endpoint we going to work on the login which we're going to use passport to
handle the login we're going to set this to passport local so let's test let's go ahead
and work on the end point so to work on the login we're going to set up passport local
so to set up passport local let's first confirm that we already install password
local inside our pcket Jon we can see passwort local here so inside the passport config.txt
use and here we're going to use local strategy so let's make sure this is correct and I'm going
to import um local local strategy form and passport local so just like this the same
way we do for Google strategy strategy as local strategy to differentiate both
of them so we going to just paste it here and the locals the local will take in three fi or
two fi here we have the user the user name field so this is going to be of type email
so we're going to set this to email so since we are using email here so let me try and this this
is so let's us user Fe and let's say email password Fe
password and we can say session here is
true is
true I think okay let's just do like this then next thing
we're going to do is to handle our call so syn this should be email
password password and I'm going to also get the done function
here so let's use our Tri cat
here and here we're going to create a service to ver verify the user if the
user is loging if the user is is so we need to say verify user and passing the
email and password so once we get the user we're going to set it to done function here
so we're going to return the done no and passing the user likewise we're going to
do for the catch we're going to also set the same way we did error and false we can do
error and false and set message to error message we can simply set error here to
any okay let make this optional so let's go ahead and work on verify user service
so that will be inside our so I'm going to go over to my ins all service so let me going to
service yeah see service here let me close this let me cl to register let's say export
constant is equals to
verify sorry verify let me P verify user service or we can just call login then this is going to
have you're going to just set the arrow and return this so we have have email which is
string then we have the uh no so let's let's set it type here say email to
string we have
password to string and we're going to do a provider to
stram so we have the password we have the provider so we're going to set the provider to default to
provider um in email so we need to make sure that the user is signing in with the um traditional
authentication way so try loging in with the email and password not using the email from the uh
Google using the email using Google the email used to sign up with Google yeah so I'm going to say
provide do so set for to email we loging in with email so we're going to first of check
the account model to find if the provider match is here and also the provider id so we're going
to say constant account the account mod find one provider so remember provider is set to provider
in.il and the provider id is set to email so we check if there is no user there we going to just
see not account you not found exception invalid email or password yeah so you can also confirm if
the user is sign up with a different you can find the email first check if the email exist in the
account and confirm if the email matches if the provider matches with the Prov provider. email
if not we notify the user that user need to sign in with Google to be able to log into the account
but I'm going to just do like this I'm going to just through invalid email or password then
we need to we need to find the user by using the account ID account or user ID so once we get the
account immediately we can find the um account or user ID inside the user model then we're going to
show an exception if we could not find the user we say not found user not found for this given
account so we need to also also um check if the password match if for instance if for instance
the user bypass this check and we can say constant is much this is going to be equal to await user
await user do remember we're going to use our compare method compare password and passing a
password so we're going to throw an error here if the password is not match we going to say new uh
session unauthorized session so let me import authorized session from app error
and say invalid email or password then lastly we going to return the user and once we returning
the user we're going to have to omit the user so we're going to use the omit method which if
you look at it here we we set it inside our user model going to our user model
you can see we have om password and compare
password and we created both of them om password and compare
password so we don't want the password to attach the response but we want to use the password to
confere here so let's save that and let's go into our passport or config and let's import
this so we are done with setting up the local strategy we need to go over to the route to
handle our rout so let's go into Auto out and here we're going to create our login
so say log. post login so we need to create the login controller so let's go into our
controller So Below the register user controller
we need to create the all controller the login controller so say [Music] constant
for to export this say constant login controller and going to say
async async
Handler so ASN we're going to get sorry object
async request
response and let's just call the arrow and here we need to authenticate the user so
we need to passing the next here we going to make use of it next function from Xpress then
we need to use password authenticate if you go over to our route here here out we should
see the way we handle for Google we use the password authenticate as the middle here so
we're going to do that inside the controller so inside we're going to say password do
authenticate so import password so authenticate and we're going
to specify the strategy which is lo like
unless what this a
error error is going to be a type of error or no and user is going to be let's
press user or set that to for so let me break this down
and then we're going to also pass
info is going to be
message string we're going to set is to undefine so let's set
our Arrow here and inside we're going to say if
error let just return
on next error so this will pass the error to our
Handler so if also if M user then we're going to just throw we're going to throw um our
our exception unauthorized here say return respon status HP unauthorized and say invite
email or password I will just set the info message here then if we able to log if we
able to bypass user is correct we can go down say request log in say
user have error unless say if error
we going to see [Music] return next error but if not we just going to return we going
to return the response here with the status of okay and message log Lo log in successfully and
passing the user and lastly we are going to and pass in the request response and
next so we are done with the um login controller so let's let's import
this so let's test it
out so make sure the server is [Music] running and let's wait for it to
um so my server is up and I'm connected to my mongodb database so let's try and
log so I'm going to click here and you should see I have login user my
Postman so I have the email and password let's try log so I'm going to click on send and we
should see user loging successfully and we can see that the password is omitted
here we have the email every other information so we are done with this so the next we going
to do is to work on the log out route so let's um go into our controller and
let's create the log out rout so this is going to be easy so say constant log out
controller we going to use our async Handler
here sync
so let me
request so inside here we're going to use the request logout I'm going to call a call back or
function then let's set the arrow and say if
error if there's an error we can log that out and withon and is telling us that the
user that there's an internal server error and log the user out to Lo the I'm going
to return a response here can use any other status I just HTP status internal Ser error
then fa to log fil to log out so once you are we've done this we can set request the
sessionals to
now and if we able to log out you just say return successfully log out all log out
successfully L out
successfully so let's set up the route the route for the log out so let's go into our route out
route and inside the auto we going to create we going to um let's that below here because this is
going to be okay you can do it up this going to be a post request we can say out rout post SL logout
to our logal controller so let's import
this so I think we didn't export this so let me copy it and paste it here and let's import this
so let's test the end points now and let's make sure that server is running so if you notice that
once we loog in the user if you look at if if I try to click on this and try to click
on let's click on the body here and click on cookies we should see that two cookies has
been set to us which is the session from passport so if we try to log out the user
so I'm going to go to log out which is a post request and let's say log out and let me save
that so let me remove none and let's send a post here and we should see Lo
successfully if we try to ask check the cookies or we click on cookies
here we should see no cookies is on the C in our post so that is it for log and log out end point
so we're going to work on the current user endpoint so let's go ahead and work on that so
let's work on the current user endpoint so we're going to go into our controller or inside our
route we're going to create the user route so I'm going to create it here so let's say user route CX
so for the user rout we going to just um that's uh constant as a constant user route and this is
going to be cl to Route router from Express we are going to set this to default here export default
user route then we're going to we're going to say user route current user and let's get user
controller so let's create this controller here so this is going to be we're going to
create the controller so let's go over to controller andless user controller
TS so inside here we're going to just say esort
constant get user controller and this is going to have our async
Handler asnc here and the
request so make sure to import request from Express
here let's call let's SC this here so we're going to get the user from the request user
remember we set the type so I'm going to say user ID I'm going to say request user
user this can be string any so just set that then we can get a user form you're going to
to create a service to Fresh the current user or you can say get current user service yeah
and let's um import this HTP HTP status. okay say status you can change the message to user
fch
successfully so let's go ahead and create the get user service remember we passing
the user inside here so let's create this so let's let's make sure to import this
first and now inside the service we're going to create user service so let's
go into a service and let's create user just service.ts
so export constant let's past this here and async it's going to be user ID of a
string so let's say constant user is going to to our we is model find by find by ID to pass user ID
populate we want to poate the current
workspace and we going to say select so want to uh want to omit the password once we the
response so select my password then if not user we just user so let's just go the error here is
not found so let's return let's import the bad request exception and then let's return the
user so let's go into our user control and let's import
this so we're going to go into our indexx
and let's create let's set the the Route M here so let's duplicate this and let's call this user
let's say user user route so in order to access user we need to have a way to know that the user
is authenticated before even trying to access the user from our database so we need to the
midw to we can call that is authenticated which is passed to the route and inside this MD here we
going to pass it here and this should be able to um verify if the user is loging if the user exist
we continue into the user route or if not then we will draw an error so let's create this middleware
we're going to say um it's authenticated middleware so let me create that inside my
middleware you're going see it's authenticated
midle TS so inside here we're going to say constant is authenticated we going to pass our
request so order from Express
response let's import that from Express and also our
next ni
function so you able to do that so the what we're going to do is to say if not requ
user or uh not requ user ID then we need to
show oniz so unauthorized please log in then we need to proceed to
the next middle way or controller so we need to proceed so let's um
ort this default is authenticated so we just going to import that
here so let's import this save that and let's test it out so make sure
the server is running now we connected to our database so let me try and log in
again so let's so it's connected so let's try log in
yeah so we set our session here so I'm going to try and get the current user here so users
current if you go to our route think we have is current and inside the index or TX we set this to
user user so let me try and say let me remove this inherit from
parents and let's submit this and immediately we should see we can get the user and the current
workspace we omitted the password and we get the current workspace of that current
user so we are done with the Endo for getting the current user so we're going to move over
to work on the workspace endpoint so let's work on that so let's start off to work on
the workspace endpoint so we're going to go into our route and let's create a workspace
route first so inside a route I'm going to click on workspace new new file and workpace
routts so inside here we're going to set up our route and let's import route from
Express and let's export the workspace route to defa so the first thing we're
going to create is the create a new workspace so I'm going to close this and let me P this
so workspace post create new and this is create workspace controller so let's go ahead and work
on the controller so I'm going to go into my controller and let's create workspace do
controller controller.
TS so inside the workspace controller we are going to let me close constant
asort constant B this here and let's use our as
Candler request and response make sure to import from
Express and let me just open this so we're going to get the
body so we need to create our validation for the create workspace for the create
workspace controller so let's go into validation and let's
create the validation for workspace so I'm going to say um workspace or validation TS
so let's just say export so we need to import
first import Z here and we need to get export of constant um create
workspace schema this going to Z
object so because we're going to use this for both create and update so
okay just simply duplicate this here and let's call this update
here so because of that you're going to create a reusable name schema and
um and description schema so name is required we can set message here and we
can also set description description is optional so just a string triam
optional and you can just simply pass in the
name you can pass in the name we can also set the description
here so that is it so let's go into our controller unless uh yeah we're
going to just say um create uh create workspace schima from
validation PS request body so let's get the user ID foral request. user doore
ID so now we need to we need to create our service so we say create workpace service and we passing
the user ID and the body so so then we need to respond response once we are done with the
with create workspace so we passing the user ID and body and let's import [Music] HTP workspace
created successfully so let me copy create workspace service and let's go ahead and create
the workspace service so inside um our service folder let's click on workspace do service.ts
so I'm just going to paste this here say let's say create new workspace and
let's export constants and I'm going to paste in the name of the service which
is create workspace service and async and this will just be user ID user ID string
let me open this
here and body is a name
String it's a
description okay description to strink or undefined so now let's let's structure the
body name description body so the first we're going to do is to check if the user
to find the user and know if the user exists in a database so let's import user model and
if not you're going to say not found so TR you not found exception us not found
so let's import this then we need to in order to create a work space remember we need to to
set the member row so we need to first of all let me get the member Row from the owner's row
so owners R from the RO model find when name is equal to owner if you can get owner you
can retrieve the ID but if not if you've notp if you've not populated this to your database
should show an error of not found not able to find the or if you have populated it in ini
data we'll be able to get the r ID which is for the owner then we can see constant
workpace is equals to new
workspace
[Music] model description description and owner to user _
ID then we need to save the workpace also we need to immediately add the user
and the workpace to the member model for new workpace member Works member
model you say user ID user ID owner um workspace ID to workspace doore ID
row owner rore ID then we have join date join out is going to be remove this new date and let's save
this let's make sure to import this and we can quickly just set the current workspace
to the newly created workspace for that user so let's import mongos so current
work user current workspace course workspace new workspace ID as the
mongus object type object ID and let's save this and let's quickly return your
workspace so let me save that and let's go into our controller and let's import
it so inside workspace route let's import the
controller and let's go into our index.
TX so for the IND TX we're going to set the uh workspace route here
we're going to pass in the mdle so let's import this now let's test
Let's test the end points now so I'm going to check if my server is
warning my server is warning so let's we already log so let's go into workpace let
me go into my workspace folder which I've listed all the end point I'm going to create so create
workspace and I can call this design team or one this is workspace create new so you know
we set workspace here and inside the route we have create new and I've provided a name
and description so let's test it out I'm going to click on send and immediately we've created
this you can look at the invite code is been generated the owner ID the ID description
and the name so if we go to our current user this should be our current workspace
now so I'm going to get the current user and we should see yeah design team which is a current
workspace so we've been able to implement that so the next one we're going to work on now is
the let's work on the end point to get user to get um all workspace for a particular user so we
are getting um workspace where user is a member so let's go over to our route and let's create
the route for that so inside here we're going to say workpace just get say workspace route
you can just copy this and paste it here and let's change this to get request I'll just say this to
all for user and just say
workp um you can say get user workspace controller
we can say this to get us space or we can just set call it get user or get workpace
where user is a member we can do it like that we can do it like that so I'll just
leave it like so just notice that not all the workspace users cre let me just change it get
user workspace or get workspace user is a member get all workpace user is
member I think this is better get all workpace user is
M so let's create a controller here so I'm going
to just go into my workspace contr see here and let's close
this so say export one
and then we are going to use our this Sync
here sync
Handler let's get this in
here let me just copy all this paste it here and you're going to get the user ID
then we're going to get all the workspace see get user workspace service and let's return
let's return the response once we get the user or workspace from the user we can call it get all
workpace all workpace [Music] user is member
service so let's copy this and let's go over to our
service and then we're going to create that here so let's see let's drag this
down and let's say export constant get all get all workspaces as a member
see
async then let's get the user ID which is
string and I'm going to just open this here so let me drag this one
so get workpace is a member so you can understand this very properly so we need
to find all member members where the user is involved membership where the user is involved
so we're going to say constant of member memberships say how with the member model do
find user ID so we're going to
populate the
workspace
ID you're going to
select L minus
password I don't think we can get okay we are not populating the user
so we can leave the this or we can just leave it here then we can just
put execute then what we're going to do next once we've gotten the we're going
to extract workspace detail from the membership so we going to say constant
workpace this is equals to
member do map because this is a list and we completed the workspace
completed the workspace we say member membership is going to be member ch.
workspace space ID so we are done with this so let's
return our work spaces the membership so
we done with this so let's go inv to controller and let's import
this let's import
this and now let's test it out so I'm going test out inside my Postman I already have so inside
my workpace you can see that I have all workspace all user workspace so I'm going to click on that
and what page all this is all so let me remove this and let's click on
submit and we can see all the user workspace my workspace and design
team which we've created if you create new one you can see if you try to create a test
I save this and I just click on submit work space is created so if you go to all
user workspace if you click on this now you can see the new T workspace
and the invite code all of them are different so that is it so let's uh
move to the next one which is to create um get workspace by ID so we want to be able to get a
single workspace by the workspace ID just like this we have in the provide the ID and then we
can retrieve the workspace so we're going to create a controller the route for that
I'm going to so let's come down here let's duplicate this and I'm going to set this to
ID now we're going to call this let me call this get workspace by ID controller get workpace by
ID controller and let's import this and let's go over to our controller which is here so I'm going
to yeah let me see export constant
let me let ASN
hand and let's uh let's set the async and inside here we need to get the uh we're going to pass in
the work space as space ID as um param we can also validate this by going to our validation
validation schema here inside the validation not workpace um [Music] validation and I think
we we can create the one for reusable one for ID here so I'm just going to do that here so
think let put it here so s+ ID schema string TR one ID is required so once you've done that
let's go over to our controller and um let's complete it so inside here we're going to say
constant constant
workspace ID is going to be equals to workpace ID schema p [Music]
ID yeah is it so let's also get the user user
ID so once we got the user ID we need to also have a way that this API will be will not be accessed
by users that are not a member in this workspace so we need to find a way to avoid the user
from accessing this workspace if they not a member so to do that we're going to create a
service inside the member so I'm going to create the service where I will pass in the user ID and
the workspace ID so I'm going to call it get member Row in workspace so this will
be able to get the user in workspace if this will be able to get the r and also verify if
the user is a is a member in the workspace so let's copy this and let's go into our
service so let's go into service here so yeah let's create a member member do
service so we going to put this inside the member service here
not inside the workspace but because this is for members so I'm going to say esort onance
is async user ID
string and we going to have
workspace
string so
let's so yeah we need to verify if the work space we can find the workspace if the workspace
exist so this should be workspace ID not workspace so once we find this we need
to if if we could not find this workpace we just say what space not found else let import
not found [Music] exception so we going to have constant member is equals to AWA member
model you find
one user ID workspace ID then we're going to
populate the row so if not member you're going to say uh you're not a me M we can say unauthorized
here we can call this unauthorized so you are not a member of this workspace
send to access this we can also set the [Music]
error access onor something like
this something like this here so if we done with this we can get the row name
here we can say R name member row member row name and we can just return the r name
so we are not going to make use of the real name in the workspace controller to together
it we're just going to use this to just check this so if if it's able
to bypass this then we can move over to our controller to retrieve the um the workspace
information so uh let's go back to so let's continue let's import this from the members
service and now we can just say um let's not get the workspace so we're going to create our own
service so get workspace by ID service we're going to pass in our workspace ID here so now
since we've already verified a user and this workpace the user
is a member we can just create that so before we create that let's just just
return status workspace and passing the workspace so let's go into our
service space
service and inside here we're going to say export [Music] constant space
what string and inside the service we're just going to this is going to be very simple here oh
sorry so let's say constant work space
wa the workspace model. find by ID work
space let [Music] select we can set if
not I think we've done this already there's no point for we can do that
here so we can just see constant
number is equals to A
wait
wa remember model of find
so I don't think we need to do this anymore since we've already done it
inside here I think we need this again you can just to find um the workspace from the
member and then we're going to just
get um yeah because I want to retrieve the so let's just uncom this let just unom this here
so I want to also return once I'm returning the ID I want to return the members inside
the um end point inside the response to if I return the workspace I return
the member so that is why I'm getting this and inside I want to populate the the row
to so once I populate the r I'm going to try to combine
the two of them together we see what speaks with
members so say do workpace do to
object I'm going to pass members yeah so now we can return
workspace workspace with me so now the member will be attaching to the workspace object so
that's the reason why I had to use this here so we can pass the workspace and we
can pass the members so once we are fetching the uh getting the user you can also get the
members so use that to check if the user is a member on the client side and return user to
you can return the user to a particular uh page yeah so um once we are done with this
let's let's um import this inside the workspace my
troller so um inside the workspace member ID you can decide to just only fetch in the members
the member which is the user that is currently loging using so once the user access end point
we can get the rule and the information about that member inside that workspace you can use
it here so we're going to use it to handle permissions on the on the Cent side but I'm
going to leave it like this so we can see that we can get a list of members or you can decide
to just get only the single member since we are already verifying that the user is L is
a member if we going into the get member rle in workspace if we a user from a different workspace
try to access this endpoint this will true so on the client side we can you can track this in by
saying if this m.2 access un authorized then we know the user is not a member in this workpace
then we can redirect the user back to his own form workspace so let's save this and let's
go over to uh controller and let's save this let's going to our route and let's import this
here so let's test it out hopefully that we should be able to get that so let's see our Endo
is so our database is connected so I'm going to go into my all all workspace and let's
let's just copy the workspace ID go into this Endo that say workspace by ID let's paste the
ID here and let's save that let's click on sent and it should give us the work space
with the members here you can see the member and the permission yeah so inside the member
you can just shorten it to only get only one and that one is going to be only the first
that a member the person that's accessing it as a member of the workspace that can be a
better approach so we are done with this now we need to create an endpoint to get
to an endo to get all workspace members here so inside this workspace controller or rout let's
go into the route we are going to list we're going to be able to let's get this and let's
so let's um set this from ID let's set this
to members SL um ID workspace ID so I'm going to call this get workspace
members controller so this end point we get all the members in the workspace so let's go
into our controller and let's create this here export Conant um controller and let's do a sync
Handler a
sync so I'm just going to copy this and let's paste it inside here so we are going to also
do um the um valid for a um yeah we did it here so let's just go into here and copy this to the
workpace the user ID so I'm going to just paste it inside the this and we next so after we've
gotten this we need to always check if the user as is a member in that workspace so we're going
to be using the get member rule in workspace so to so let's copy this here let's copy the get Row
in member workspace and this will remember if you go into the get R member workpace we can get once
we confirm the user have access it's a member we return the r name so we can get the r name
and you know the r name is unique so I'm going to go into my controller and I'm going to say
console and let's get the ru those that don't have access to that endpoint will be thrown an
error that they can't access the Endo because they don't have the permission this endpoint
here we have this controller get workpace member controller we can also have a permission to set
if we go over to our R all rules let me go to the in which set for the rules permission
here inside we have manage workpace we have U other um options here other permissions here
but to for this particular controller I'm going to set this to view or so only only users that
has the permission of view or we able to access the get workspace member controllers so to do
that we're going to create a helper function and this function will call it rad guide so R guide
will help with taking the row and taking the permission and confirm if the user has the perm
to have the permission to access that Endo if the user is a is is an owner and the permission
we give it is to view or only we confirm if that owner has the view only permission then we can go
further to access the import else we are going to throw an error so to do that I'm going to press
come down here and let's name this R guard which we're going to create in a seconds so R guard
will take in the RO and permission is always in the list you can have multiple permissions you can
have in a in this s controller you can have many permissions for this controller so we're going
to set this to we're going to get permission from up enams and going to say dots only you
can add more permission here if you want but I'm just going to set this to view only then inside
we're going to go ahead and create this R guide so to create this R guide we're
going to go into our U going to go into R and let's create Rog
guard TX soar 2x we are going to uh export constant Ro guard this
is going to be it's going to take in the row and this row is going to be um a key of type
of type of row permission so R permission is coming from the UTS yeah then we're going to
have the required so the required permission the user we have or the m we have is going to
be we're going to just say permissions here let's put comma here and this is going to be permission
type so we're going to get the permission type from the and I'm set it to a list so let's let's
say the arrow and let's open this so to get a permission we're going to say permission yeah
permissions is equals to change this to small letter permission is going to be equals to the
row permission and we're going to get the row so let's pass in the row and the row might be the
owner admin or member and this will retrieve the permission for us yeah so now we need to say we
need to check if so we're going to do a check here we going to say if the row doesn't exist
or lack require permission then an exception so we're going to call this constant has permission
is equals to required permission do every we're going to say permission so you're
going to go through all the permission in the required and we're going to set
permissions do include so let me break this here that include the permission
so we're going to get everything from the required and pass it and check if it has if it's included
into the permission from the um R here specify so we're going to thr an error if this so let's
dra an error say if not permission if not has permission let me the S here we're going to say
unauthorized and we can set uh uh we can leave it like this so you we don't have the necessary
permission to perform this action so we can save this so if this doesn't go true then
it's going to continue we're going to move on to the next so nothing will happen so let's
go to our workpace and let's UNC commmand let's import this inside the controller so let's import
this and now think we so let's call we're going to move on to get the uh members service so I'm
going to say constant members R so this we're going to get and get workspace member service
and we going to pass in the workspace ID so this will give us the members and all
rules so this will give us the members and all rules here so let's go ahead and create
this service inside the workspace service so I'm going to go scroll down to to my service
and um let's um so I'm going to close this here this is workpace by ID service so to
get all members in the workspace I'll just put comments here and let's sa constants and let's
let's paste the the name of the uh of the work of the service we're going to create
here we're going to call it get workspace service and this will be async this will
take in the workspace IDE here and this will just going to return this let me put equals
to here so this is okay so now we need to fetch all members of the workspace here so say constant
members is equals to await the members member model do
find we going to find the workspace ID then to find out you're going to
also populate the user because you're going to use that to list out the user
name so I'm going to say po user ID with name email profile picture
profile picture then we're going to subtract we're going to um omit password then we're going to also
populate so once to populate the RO of the user just you just need a name for
this we don't need the permission here so why we're going to just list out the RO
so we so admin or owner can switch can change user R so we're going to say rules Ro model do
find you're going to just get the name [Music] one and them underscore ID one
so we are selecting name and ID and we're going to say select
permission you're going to we not going to return
permission so let's save it like this and let's write this to Lan so let's return the members
and the rules for this workpace so let's go into our controller and let's import this
so what we're going we're going to return the response for this is we going to say
return response do
status H HTTP
[Music] C and this will just take a uh message you're going to just pass the message members
and the um rules like this so if we save that let's go to our route and let's import
this and then let's make sure this Endo is working we're just going to uh let's
just wait for this to connect to our database so meanwhile we're going to go let me go into
my Postman and let me click on this are going to go into all members all members so the all
members is going to be a members ID so let me get uh the workspace ID and let's just paste it
here save it and let's send it so I'm going to make sure uh remove this yeah so let me send it
again say use okay think we made a mistake here cannot populate here so let's go into workspace
Service uh yeah so this is wrong should be user ID so save this and let's wait for this to run
so let's wait for it to connect to the database okay yeah so let's click on
this again and this should give us the actual response so we can see the member ID the uh
user information the workspace the row of this member and this is the rows that we have we're
going to use to list out on the drop down on the client side so we are done with this
so let's work on the workspace analytics Endo so I'm going to drop my my terminal going to close
that and below this I'm going to say get analytics ID and we're going to say get workspace antic
controller so this will get the analysis of the workspace that is going to calculate the
number of taxs um completed tax on overdue tax so we've done this so let's go ahead and create
the controller for this so I'm going to head over into my controller and let's close this say export
Constance async Handler unless say a sync
yeah so let's copy this here the request and
response and inside the route we specify the ID so we're just going to use the same
the workspace ID here with the schammer to validate the ID so you can copy the same
thing again there or you can just comment this out there's no point uh handling for
is we can we can commment this out so there's no need for this not the um we can hide the rad guide
and leave only to confirm the users from that um uh workspace but let's just leave it like
this so we're going to create our type uh service here and this service will
be constant this this is going to be a with get
workspace analytics so let me just get this here and
service and let's just open this here so this will take in uh the workspace ID so I'm just going to
copy the workspace ID and pass it to it so this will return us the analytics and we are going to
send it back to the client side so let's go ahead and create this uh service for the for the anal
so let's go into our service workpace service and let's export on get workspace analytics
async workspace
ID is going to be
string and let's R let's call this so inside here we're going to get the current date
first because we want to be able to uh query the database count the number of
documents number of tax and also the completed tax so to do that we going to say current date
is going to be equals to new date then to get the total tax say total tax done
for all projects it's going to be equals to um the tax model let's import this do count
document and we're going to pass in workspace so workspace is going to be a workspace ID uh
workspace does not exist in workspace ID does not exist in uh in tax so so if you go into
the tax model you should see that we specify uh workspace not workspace ID so let's go into our
controller not controller workspace service and inside here we're going to get the total tax now
we need to calculate the um overdue tax so we say constant overdue overdue tax this is going
to be equals to AWA um tax model do we're going to count the number of documents that is overdue
so we're going to say um workspace it's going to be workspace ID then we're going to say due date
we're going to use due date to be we say uh if this is lesser doar sign less time current
date so yeah letr then we need to also filter out the and we should
said this is not equals to so we're not going to calculate we not going
to count the tax are completed so or done we say tax status in know do
done so we're going to say not equals to not equal to uh tax. yeah so we're going to
exclude um the completed tax then we're going to calculate now for the completed T the constants to
completed tax this going to be equals to we going to do the same thing here
so let me just copy this bring it here then we're going to say status
[Music]
tax yeah so we done with this so we can just do constant
analytics we can say analytic is going to equals to total
tax um overdue tax so let me correct this overdue tax and then completed
tax and let's return analytics so let's save that and let's go into our controller and let's import
this and there we're going to get the analytics here and let's return the response so I'm
just going to return the response here and let's just remove this and set the analytics
here so we're going to replace the message here with workspace
analytics retri successfully let's say let's go into our workspace route and let's import
this so we are done with this so let's test this end point out so I'll go to my um so my folder
workspace folder here and I look for workspace and litics so I'm going to click on workpace analytics
here and here I'm going to get the workspace
ID workspace analytics and I'm going to replace this with this ID here the workpace ID we can
see that we have analytics on the ID here so let's try and run this and hopefully it
should we should be able to see so let me try and remove this set to inherit us so
let's click on send and we should be able to see Zero for all of them so total TX Z over
t z and completed tax Z so we've not created any tax at this moment so we've been able to
create uh all this API RS so we're going to look at the next end point which we going to
build um is the um change workspace member R so the owner the owner only has the permission
to change uh members from Members Ru to admin R but can't change his own Ro yeah so I can't
switch anybody Ro to owner so owner is set to owner and the uh the member can be moved
to admin and admin can moved back to member so let's quickly create the route for um the route
for the change member R so this is going to be a put request so I'm going to set it at the top
here so I'm going to just say at the top
here and we're going to have change we're going to have change member rle and we set the workspace ID
so this is going to be change member row [Music] controller is a put request change workpace me
change member and the workspace ID so let's create this inside our controller and let's
let's close this down let say export constant and let's async [Music] Handler set async
and let's copy the request or response from this and let me paste it inside
here so now we are going to also get the ID let's copy this here the workspace ID
and the user ID and we're going to also copy this but this is not going to be U
view only so we are going to change this from uh view only to change
member so we know we have change member permission so I'm going say dot change member
permission so if we go into permissions we can see chain member rules
here so if the user or if the owner has or anyone that has the permission we'll
be able to change a member row so I'm going to say constant let's create the uh service
for this and this service we going to pass in the uh row ID so I also need to also we also forget
to pass in something here after got the workspace user ID we need to get in the r ID which we are
going to the member ID and the r ID not the user the user ID might be the owner then the person we
want to the member we want to um change so we need to create is validation for that for the
body so I'm going to say constant and this will give us member from the body member ID and Rule
ID so we're going to call this so let's go into our let's go into our validation let's
click into workspace ID and inside here we're going to um PR come add
workspace ID let's go below this and let's export this [Music]
constant and set
object we're going to say row ID and the members ID so let's set
this like this we are done with it so let's um go over to our controller and
and make use of this so I just go to my controller and let's set and let's pce the request
body and let's import the change R
schema from validation so now we need to create uh the service so the service we taking the uh
the workspace ID member ID and the role ID so I'm going to just space so it's going to give turn
back as the member so let's create this change member row service we taking the workspace ID
the member ID and the r ID so we're going to go ahead and um implement the the so let's just copy
copy this and let's go into the service and let's create this export constant and change member will
async and let's just so let's also set the um argument here we say workpace ID string
remember ID string ID make sure everything is aligned like this and now we need to first of
all check if the works user um if the workpace ID exists I think we've already added this
here so we can skip that here we know that it's
works so then we need to get the row a row here so I'm going to say row is equals to
our row model then find by ID row ID so we are trying to get the the row ID from the r model I
still want to also check if the workpace is so in case the was removed so I'm going to
also check this workspace work modifying by workspace ID if not just through a session
let's just put it here so then we able to confirm that the workspace is valid
and the RO ID is valid now we need to be able to find the user from the member uh model so
we're going to say constant member this is going to be equals to await member model. find uh by
ID and user
ID so why is not M model they find okay sorry not find but I def find
one find one and this will give us user ID and this will be called the member member
ID then the workspace the workspace uh ID so we confirm if this user uh this member is um
if this member we were trying to change or this member ID is actually a user in that work space
then we can be able to uh TR an exception if not so remember is not found in this workpace noce
that this check here is not for the user itself that's accessing the Endo it's for the user the
member when they want to change his role so we need to confirm that user is actually a member
in that workspace so once we confirm that the user is a member the member is uh the
member ID is actually existing in the members model then we can go ahead and change the row
so going to just assign the row to equals to the row so we've gotten the row ID which we
want to change to for instance if the member has a ro of member and we want to switch the person
Ro from member to admin then we need to submit provide the admin ID here admin ID and this will
be able to confirm we check if the row ID exist then we assign the member R to equals to the r
which we've been able to find here so once we find this we're going to save it into
here so once we save it we [Music] return can return the
member so once we return the member we can go over to workspace and let's uh import this yeah
so inside a controller we are going to uh call our response to submit this uh to return this
member to the client so response status is to be okay and member will change successfully
I sending the member so we can currently change this end point because you've not
implemented the invite we are going to do that very soon so we're going to hold on
on testing a change workspace member for now so let's move on to um working on the update
workspace workspace or or let's go ahead and test on work on the invite so we can
be able to test the change workspace member in action so let's go ahead and work on so
before we go ahead and work on the invite let's go over to our route and let's import
this so this invite will refer to as join work and Jo workspace will not be placed inside the
workspace controller because we adding the user and the workspace in a member model so I prefer
to create a member controller and place this Endo there so this controller there so let's
go into controller and let's quickly create um a a controller we're going to call this
member. [Music] controller TS so once we create this uh member. controller. TS we
are going to uh we are going to Let's create the controller here so let's
export export uh constant so constant uh what to call this Jo
workpace controller [Music] and we're going to say our as
Candler and as
request request from Express and a response from
Express and let return return this so we need to validate the invite code because the user will
have to provide we have to provide the invite code to use to identify the workspace and be
able to add the user who is accessing this page to the member model so to do that we're going to
Simply use our Zord um validation here so I'm going to just import Zord here and say Zord
string. Pi so we not creating any usable schema we just sending it here to Z string p and we're
going to get request par invite code the invite code will be pass to the endpoint so once we uh
do that we're going to uh pass in the user ID so request user ID so before the user can access or
call the same points or the member which want to join the the user want to or the guest user
which want to join the workspace we require them to sign in first and once they sign in
they'll be allowed to call hit uh submit a button that we call this endpoint so we can
call the service here so I'm going to call this um constants and this will give us the
workspace workspace ID and the role of this user so this will be our weight of
uh join workspace by invite and we're going to the user ID and the invite
code so we going to also we going to quickly just set the return status status here and
the let's return the response and also import the status here HTP okay and sucessfully join
the workspace workspace ID and the role which is assigned to the newly joined
user so let's go to uh service and let's create this so inside the service we have
Member Service already existing here so let's uh let's create this here so just
say uh export constant let me close this join workspace uh by invite you can just call it
service and this async
user ID string
invite invite code string and let's just set this like this okay let's put a comma here
so first of all we need to be able to find the workspace by the invite code I remember invite
code is unique so we're going to say find workpace by invite code so we're going to
get the workspace model find one pass the invite code and execute this so if not we
say invite code invalid or workpace not found then we can check we are going to check if the
uh if the user is an existing member so we don't add the user one adding a single user
in multiple workspace or in the same workspace so we can there a check if the user is already
a member so we say existing member member model find one we pass in the user ID and the
workspace ID and ex it so you're going to show us if is existing user you can show a new bad
request exception I say you are already a member
so say you are already you already a member of this workspace so let's uh
so now let's get the default uh row so each member joining is going to have a roow of
member so we're going to say find um inside our role model we're going to import this and let's
get name that has rules. member so let's import rules from the enum and if we get
that we have to check if this exists if not let's draw an error so we going to say new
not found exception we can see what does not exist or no not found let's just say oh not
found then if if all this is true if the user um bypass all this check then we know that the
user is not a member so we can immediately add the user into the members model so I'm just going to
say user so add user to workspace as a member so we're going to add the user here the workspace ID
and the row the r ID so let's return let's return the workspace ID and the row so the workspace ID
and the name so we are done with this so we a to find the user bed on invite code we a to check if
the user already exist and if the row model uh we get the default um Ro which is member
and then we assign we save this user and the workspace into the members model so we going
to go into the controller and let's import this so let me call this service here so we are done
with this so now we can try and test to invite user to join the workspace so let's make sure
our server is running so uh we also Focus we also Focus something we didn't implement the
route for the member the member controller so let's create that so we going to com r
s so inside the route we're going to just get the uh router form Express so let's import
that and let's just uh s to um post request workspace invite code join for
this join workspace [Music] controller and let's let's set export this to
default the post request we're not going to pass in anybody so just only the um
param here and we're going to set Jo workspace controller and Export
defa members throughout so inside the index TX I'm going to just say
there so the the members to will also have the the is autic attached to it the middle is going
to place because the user need to be registered before he can or she can access this Endo so let's
import the member route and then let's confirm our server is running and API is database is
connected so database is connected so let's test this out so I'm going to go into my uh V move here
and I'm going to go into uh invite I'm going to go into members I say join workpace so before we
do that let's copy the workspace ID here which the user want to join so before the user join let me
create a new user so I'm going to quickly create a new user here I'm going to call this uh Sam
and let's try let me create this user
now so user is created and the user let's so let's try loging this
user so I'm going to log in this user here
so now the user is talking so let's try and go and join this user if you click on get current
user we can see this is Sami Gmail so let's get the workspace ID here
from the URL I mean from the uh yeah from this here and let's go into join workspace
and let's let me replace uh I think it's not the workspace ID is the um invite code so let's go
ahead and get this workspace so I'm going to go into workspace by ID and you can see
that this is the workspace here the design team is the workspace which was created by
um this user so we can see the invite code here so I'm going to copy for design team
workspace so if we go into join
workspace I'm going to just REM this here and let's replace this with let
me remove this I replace it with design team and workspace invite
code and since this user Sami is loging let's click on send
so you can see the Sami is now a member of the uh of this workspace so let me try and
fetch all workspace now from this workspace so see uh let's get all members of this workspace
this workspace is a workspace s joint which is Creed by John do so it's qued by John do
so you can see JN do is the owner it has a ro of H so I'm going to try and call this
again and if you scroll down you can see Sami is added to the member great and it
has the row of member here so this is great this is great so let's go ahead
and test the uh change end points so in order to test this uh change workspace rle
we need to provide I think wey we need to provide the workpace ID the member ID and
the r ID which want to change to so we can go over to Sami and you can see Sami ID here
so just copy Sami ID then we can scroll down to where we can see oh want to change um Sami
from Member row to admin row so make sure to just also copy the admin so or you can
leave it there we can just go over to log so let's log in to uh to joho example.com so I'm going to
log in to this user this user and let's go to our end point to say change member rule a put request
so so member and let's remove this
uh let's remove the ID I specified here let me remove this ID so let me go ahead and get
the let's go to the join workspace and copy this not okay yeah we can see the workspace ID here so
we can copy that from there and let's go back to uh change member row and I'm going to just
paste this here you can see workspace change member Ru and I'm going to set the ID of the
workspace then inside the body we need to provide the r ID so I'm going to remove all this hereas
I'm going to provide the r ID and member ID so to get the RO ID and member ID we can get that
from all all members so click on all members and once you click on all members you can scroll to
where we see Samy so this is the user we want that's existing in the RO in the workspace
created by John do so I'm going to copy the ID so inside the user ID you can get the ID of the
user so uh I'm going to go into my change and I'm going to replace this with the user ID the
member the member user ID or something like yes you can can rename this to member user ID
so let's go over back to all members and if you scroll down to the button you can see we listed
all the rules and the ID so we can copy the admin the admin ID here and if you go into uh
change R uh yeah to change R so if I if I paste this here I save this and immediately if I click
on send we should see uh row has been changed so joh do now is I mean uh Sami is now an admin
to confirm that we can click on uh let's click on all members and you can
see some here currently R is member if I click on this end point to run
again and you can see it has change to admin so to also show that this um
permission R guide work we can try to go and log in as uh the admin I think um ad
does not have the permission to change so let's go into R permission
here admin does not have the permission to change a member R so I'll go into login and
I will I'll move in as Sami Sami gmail.com so Sami is an admin so I'm going to log in
as Sami and I'll go over to change uh change member row so once I click on change member row
I'm trying to assess the end point here this is the workspace ID and this is the Endo I'm
not changing anything I'm going to use this as example so once I click on this Endo you should
see that you do not have the necessary permission to perform this action assess
unauthorized so you can see that before even trying to even check this uh get the access
the service R guide has blocked this from block us from accessing this um Endo so this is great
this is great so we've been able to test this Endo for the change workspace member
Ro controller so now let's move on to uh work on other mpoint which is the update
um going to work on the update workspace API so let's work on that so let's work
on the update endpoint for the workspace so I'll go into my workspace route and let's um
let me go into my workspace route and below the create new I'm going to just P it a put
request for update and the workspace ID so we're going to say update workspace by ID controller
so let's just this and let's create the controller for update so I'm going to go
in my controller and let's sport constant paste it here and let's get the async
Handler and let's say
async let's SC the arrow and let's let me copy this request and response from here
and let's place it inside this so inside the update we are going to get the validation for
the data been passed I think we've added it in the create if you go over to create
schema we can copy this just go into the you can see we have the update workspace
schema here so let's scroll down to this and let's paste this and change this to update
update uh workspace um update workspace schema and we can save that so we are going to also
get the going into the route remember we passing the workspace ID here so we need to also validate
that too so I'm going to use workspace ID schema which we've been using I'm going
to pass in the request param ID so below here we're going to uh we're going to get a user go
the user log log user so I'm going to get user C request user ID now we need to also
check the user R and guide the endpoint so only um user with permission of edit workspace can
access this endpoint so we can see we've able to use the get R in workspace pass the user ID
and workspace ID I retrieve the pass the into our R guide and pass the permission do edit
workspace So Below there we're going to create our service so we can call this uh updates update uh
workspace workspace um by ID service
and let's make sure to add the so to so we're going to pass the data so I'm going to struct
this to get the name and description of the workspace and let's pass it here let's pass
the workspace ID going to pass in the name and say description so we going to get the
workspace from the as get the workspace you update workspace and let's return that uh
response here so we can see hcp okay message workspace updated sucessfully so we need to
work on the update workspace by ID service so let's copy this and let's go into um workspace
service so I'll scroll down to um service and let's close this change members R service and
let's a constant export constants and let's space this it's going to be async
and we're going to have in the workpace ID which is a string name String and um
description
string and let's just set this to Let's close this so let's break this down so
then inside the sorry you need to add add the arrow ke Arrow function
here so this will be description will be optional but the name is
requireed so um we're going to get the workspace here so workspace is equals
to workspace model
do find by by ID I'm going to say workspace ID and then we're going to say if not
workspace let's dra a not found
error so not error workspace not found so if there so it we can update the workspace here
see workspace name or we just set the um the name already exist in the workspace likewise for the
description you can do that and then we need to save this so let's save this and let's return the
workspace so save that so now we we are done with the update workspace so we're going to go just go
import that inside the controller so let's go into the controller import workspace uh so let's save
this and inside the route the workspace route we need to import the controller inside here for the
update so let's make sure the server is running and let's test this
out so uh to update this I'm going to go into my update so let me let me clear let me click on this
and let me scroll down to where I mentioned okay I place the update workspace endpoint so before I
go there I'm need to get the um workspace you want to try to uh I'm going to copy the workspace which
we want to update I remember I'm still loging as Sami and Samy is the has the admin R in in the
design team workspace which I just copied there so if we go over to update workspace I'm going to uh
change this to the ID workspace ID I copied and here we can have um let's say workspace updated
and let's go over to where we have the workspace just click on workspace by ID and we
can see design team this and this the design team workspace we can copy this and let's go to update
back and let's paste this here so we can see um workspace and there
anything workspace updated or we can just put us here
and also change this to designer so to see if this will work so
let's save this and let's try it out so I'm going to try and remove all
this we have the body we have the um ID and the local 6,000 with
the workspace update the same with this so let's try and click on the
send yeah so it shows this Arrow here you do not have the necessary permission to perform
this action so if you look at our end point or controler we go into the permission We Men
We stated that owners only have only owners have the permission to edit your workspace
which is created by Him so you can see we don't have edit workspace only edit project
on the own permissions we have edit workspace and create workspace so let's save this back
then let's try and log to test this we're going to have to log in with owner of this workspace
and the work owner is joho example so I'm going to log with joho example.com and once I click on
go over to update this workspace design team and I change to designer teams I'm going to
click on that and you should see the end point um you can see that just save just updated the
workspace this correctly so if I try to go over to get the workspace per ID this is the workspace ID
and if I click on it from design team to change designer teams and the description has changed
so this is this is great so we are done with the update Endo so let's go ahead and work on delete
Endo so be able to delete this um to test delete workspace so I'm going to uh go into my workspace
route and below here I'm going to um let put the workspace delete here so workspace rout do
delete and this is/
delete and we're going to pass in the workspace ID
I'm we're going to have delete workspace ID controller here so let's copy this
and let's go over to our controller and let's create this end point here so say
constant delete controller you have the async Handler to
handle we have ASN
so I'm going to copy the request
response so here we're going to also get the workspace ID from the params
and we're going to also um check if the user has the permission to
delete workspace so we going to so before let's get the user ID
and let's change it from view all to delete
workspace so if the user have the permission then we can go ahead and create our constant
and let's create the service so we're going to call this delete workpace by
ID service here and we're going to pass in the workspace I and the user
ID and you're going to get our current workpace here so let's go over and work on this in our
service so let me um going to my workspace service and I'm going to close this and say
export constant delete service is Closs to async I'm going to have a workspace ID to string and
we have the user ID to string so let's call this so inside this service we going to we
going to first of all to delete this workpace we have to perform different action here so we
need to first of all find the workspace with the workspace ID then an error if the workpace
doesn't exist and also now we need to confirm the workspace owner is actually the user so
then if the workspace owner um is equals to the user ID like if it has the if it's one that has
the workpace then um like if you're not the user owner if you're not the owner of the you not you
don't have the don't have access to delete this workspace then we also going to um find the user
then first of all we're going to have to delete the project created for that workspace the tax and
also the members then we're going to change the user current workpace for check if that workspace
want to delete is actually the current workspace in the user model then we'll have to remove it and
update it with the with the workspace refetch from the workspace model so to handle all this
we're going to use transaction here because of so many using multiple U making multiple action and
we need to use contion so if anyone feels it rever back so so I'm going to um import mongos here and
this is a mongos start transaction and we're going to set and start session then we session to start
transaction let's use our Tri cat here and we're going to try and get the workpace and show the
aror okay so if the workspace is not found so we just say if works if Co workspace workspace which
workspace model to find by ID and workspace ID the session that's session so if works not workspace
true new not found ex workspace not found then we can quickly just do u a check here so we can send
this message if this pass say workpace owner string if not equals to user ID then you are
not authorized to delete this so only owner can delete this so even though we go ahead and remove
the permission we still have this check that only owner can delete this workspace so let's um import
the bad request from um app error then we need to um get the user from our user model so say a user
model find by ID I going to pass in the user model and make sure
to set the section change the section to the user model to
so this user model yeah then if not user then we need to show that the user is not
found so we just need to make sure I don't think we need to check this because we uh
so let me check my controller to confirm we check the user inside the members Ro workspace
okay yeah you can just continue like this so if not not F so let's just leave like
this then we need to delete the project all project that's assigned to that workspace ID
that has that workspace ID so we say project model delete menu so let me import project
model so if you go into project model we know that we have project has a workspace
has workspace here so we going to set that so I think it should be
workpace not workpace idea workspace we should have changed this to workspace ID
but we've already saved that in the data so this should be workspace ID not workspace but
we've done that already so uh change that to workspace then for the tax um for the tax we
need to also delete the tax assign attached to this workspace so we need to do outwait um tax
model that delete men so if you go into the tax model we can check that we pass in the workspace
here so let me let me setle like this and also um set the session
here so set session
again so I just want to [Music]
confirm it should confirm that this has workpace
so after the tax has been set and we change this so we should also um
call the you have to delete the members so yes members model find uh not find delete
menu we workspace ID yeah just to workspace ID so real workspace ID is workspace so in
the members model we set this as workspace workpace ID right in the P model we set it
to so you can just change this to to workpace ID in the model before you can join it here so
I already make that mistake so I'm going to just continue with this so you should know that this
is workspace ID so once we do that we going to connect the SE change the section to this
so now it's time to update the current user Uh current workspace in the user
mod so we need to update so we need to check if it matches the workspace we want
to delete so we set if user. current workspace do equals to workspace ID
then then we need to find the uh we need to find the user inside the members model
so we find the user in the members model so we say member workspace so which member
model find one the user ID and we change the section then we need to update the user so
if is the same then we need to get this and update the user to um you can just pick any
workspace from there so we going to say find anyone find one and let's update the user
current workspace to member if there's member workspace then member workspace do workspace
ID
no we say this to now so you have to you can find a way to enforce the user to have a workspace if
this is not then once user try to log in there will not be any current workspace for the user
so I'll just set it now here and we can save this and passing the session so I'm going to save this
here and let's set the session to this so then we can we can then delete the workspace so so let's
delete the workspace so with workspace delete one and then the session so once we are done
with this then let's commit the transaction so our session does commit transaction and then we
can end the the uh session so we then return the um let's return the the current workpace
so let's return the current for space return current for space and then we can just abot
is if any error and end the session once we um abot this I'm going going
to a session transaction session end session and throw this error so able
to get the current workspace for this um for this end points so able to delete the
whole delete the workspace which the user wants or the owner want to delete so let's
go over to our controller and import this so go into my controller and let's import
this from our service here so so let's return this let's response say return
response state to thep okay okay workspace sucessfully and we just send the current
workspace so this will help us toir the user to this workspace so let's save that
and let's test this endpoint so uh yeah we need to go into our route and let's import
this so this is it so let's go into workspace controller and let look at everything is
okay make sure that everything has the session change to the uh to the model here so we have
every session change to it and um we committed the transaction and we also end the transaction
so let's just go over and test it so I'm going to check still loading so let's wait for it for the
server to load complete so now let's test this Endo so I'm going to um so uh we're going to go
into okay we are loging with the creator of designer team so let's go and delete designer
team so to delete the designer team I'm going to go into uh workspace per ID so I can get
the ID of the workspace of the team I'm going to copy the ID here then I'll go into where
I specified the L workpace end point in my in my um Postman and let me just remove all this
here and I'm going to paste this workpace ID here so let's save this and let's try
it out hopefully you should delete the members the project which you've not I
want to show how it show it delet the members so I'm going to click on send
and so deleted successfully and this is where with the current
workspace is so if we go over to um workpace by
ID let's try call this uh workspace you see workspace not found so if we try uh the click on
all user workspace if I click on that you should see uh we have the my workspace and test workspace
and if I Tred to find the workspace which I copyed we said that we we got the current user
workspace to we set the current user workspace for this user to this one we have here so this is
the one that was created last so we didn't make any changes we didn't update theace because the
current workpace workpace for which we deleted is not actually the current workspace for the um the
user which is um J do so let's cancel this so we can see that the designer team uh workpace
has been deleted completely so now our end point is working so the next thing we going to do is
we're done with the workpace all workspace apis so we're going to move on to work on the project
end point so let's go ahead and work on that so let's work on the project points so I'm going to
create a router for projects and call it project. router r.x and inside the project we're going to
get router from Express so I'm going to close this and let's make sure to import router from Express
we going to set this to default to project rout so we're going to first set our first endpoint is
um project route Al to create we going to work on Create and project so we're going to set this to
workspace workspace SL we going to have the workspace
ID I'm going to say slash create
and then we're going to set a router here so we're going to
call this create project controller so let's go it here create project
controller so let's go ahead and create this um controller so let's go into our controller let's
close all of this let's close the config and let's create a new file here and let's call it project
controller. TS now let's say export
constant create project controller we're going to
get our async Handler from middle okay sync and let's get a request
from Express and response from
Express so so create workspace is a is a post request so we're going to go into our model and
let's see what post project requires us to pass we need to pass name Emoji description and also
attach the workspace ID here so let's go into our controller and let's get validate the body which
is um the name description and Emoji so I'm going to for constant body you going to create this you
know this schema Z validation schema for create project so we're going to do that very soon so say
p and we can just pass in the request body we can do request. body like this this is okay so let's
go ahead and create a project and validation here so I'm going to create a new file let's
say project [Music] validation dots so um we are going to do this what we did going to first of all
import Zord in this file so let me close this and let's get export constant create project
cre project schema is going to be S said object so as object then we
have emoi which is going to be of string so since we're going to also work on the
updates we going to create a reusable for the Emoji name and then description
so you can change this to updates
here so to do that I'm going to create Theo remember is optional because we set
the default in the project model we set a default so require this first so we can set emoj schema Z
string frame and this optional then we can get the name uh the name name is going to be to be
Z screen Z screen string minimum one maximum 255 likewise the description likewise the
description is going to be optional too so destion Z string VI and optional and let's pass all this
here there a name to name schema description
description to description schema so let's just copy everything we have here and let's paste it
here so lastly we're going to also um I just want to complete this by also specifying the
project ID schema just the same way we did for workspace ID so I'm going to do that now we're
going to use that for other endpoints so just set this to minimum one and let's just go ahead and
work and import this great project schema in our project controller so I'm going to import
this so what we're going to do now is to also um since in the route we are passing the workspace ID
we need to also validate that so we've already uh we've already have we already have validation for
that so we can just get that here it's a workspace from workspace schema and we can import that from
validation and passing require and request par um workspace ID so now we've gotten the body and the
workspace so we need to also get the user ID so we get user ID from user ID request user andore
ID so we also need to do the same way we did for the um some of the workspace endpoint which we
have to check for the user R so we are going to you can go over to workspace and import that so
I'm going to just say that here and we can just say get member R in workpace import that from
um members service and pass in the user ID and workspace ID to get the row then we are going to
just get the say row guide and let's import that passing the r and let's pass in the permission
let's pass in a list of
permission so import the permissions do so you should have create project so only
admin and owner can create a project have access to create a project so let's save
that and let's let's set up let's connect create up service so say await just create
project service and this you're going to pass in the user ID we're going to also pass in the
workspace because we need to set the user that created this project so let's uh let's quickly
go ahead and create this inside the project service so I'm going to go into let's close
model close uh route so inside a service let's create a file call Project do service CS so you
going to see export constant create project service this is going to be
async and let's say the arrow let me fix this so inside the uh
service we going to get the user ID and the so I'm to say user ID which is string the
workspace workspace ID which is string so we also forgot to pass in the body so
let's also pass in the body here so let me pass in the body here
so let's go back to the service and we are going to get the body here the body this is going to be
let me add a comma here so inside the body we're going to have Emoji which is optional to string
we will have um the name so this can just be have name String [Music] description optional string
so say like that so now let's create a project so project we going to say constant oret is equals to
new oret model and let's open this so to to add um since Theo and description might be optional
so don't want to set anything undefined in the database so we're going to do a d structure here
then we're going to do um open a bracket here and let's say body dooi if this we going to set Emoji
it will bodyo so if this assistent but if not we're not going to add anything to the database
so let's say name is body name description is probably the description and we can have
workspace workspace ID and created by it's going to be set to the user ID so let's save
this and let's turn the project so we didn't check the workpace ID because we already
checked that already with this uh get member workspace so you can do this flow like this
so I'm going to return this and let's go over to our controller and let's import this from
the project service so we need to then return so let's get the uh project and we're going to
return the projects in our rest response so HTP created HTP uh status created and we say project
created successfully and passing the project so let's go into our route and let's import
this so once that is done so let's go down to our index of TX and let's
just copy and paste this and change this to project and let's get project
route so we able to set our project and we have on MW attach to it so let's go to our
project and let's try to test this endpoint so it's going to be project workspace workspace
ID and create so let's test this Endo make sure the server is connected to the database
so we're going to test this so which uh let's create a project inside test work
space so I'm going to close workspace here and let's go into project you can I have
list of project I'm going to create project upate project and so so inside the create
project and point so I'm going to click on that and we can have a local 8,000 API
pet workspace and then workspace workspace ID which is here then lastly we have our create
the create which specifier is there and this is a post request so let's set body
so I'm going to just remove this ID this and workspace ID and use the test workspace let me
save that so the project we're going to create we can create a front end
components we can give it content components notice I didn't specify
emoj here that's because I want to do this without Emoji but you can add Emoji
here and this we uh I can just give it an emojy so I can also give it an em here I this test I
give this emoi and you can see the Emoji here so once I click on submit so let's make sure you save
this and let's try and send so we can see the project is created and the workspace is set the
user created by ID is set ID and the workspace here so we have the font and comb and everything
here so we've been able to set up the uh create the create project endpoint so we going to create
the uh project now is to get all project for a workspace so inside a route we going to let's
come down here and let's let's create this a project route get workspace workspace ID and all
so this we say get all project in workspace and we can call this get all project in workpace uh
controller get all all project in workpace controller so let's um save this and let's go into
our controller and let's create this so it's a export constant I'm going to P this and let's use
async isnc
[Music] Handler here and let's pass a let's SC the arrow
first so I'm going to just copy this
here let me paste it inside here so to get all workspace we going to only pass in the workspace
ID so we need to validate we to validate that so say Pi uh require request I mean haram's workspace
ID so we also get the user ID too so let's get the user ID we also confirm the user
is a member of this workspace viewing this project so we can copy this two of
them and let's just say this to view all view only or you can call it view project
a few project anyone so once you are able to are done with this so let's go ahead and and call uh
and call the service so um for this end points I want a way we can be able to pagate this data so
if we go over to our route we can be able to pass in page size and um and page number so
let's go ahead and do that so this is going to be passing to the query param so inside the project
controller below let's say constant page size this is the limit and we going to say page number
so yeah we're going to convert this from to con it to integer to number say requir do
query H soorry request.
query do p
size and let's just set this to a string because this will
string then pass to URL so we can just set this to you can set a default for this to
then if not pass because this is going to be optional and we can just copy this and
let's do that for page number and this will be page number and this will will set to one by
default so now we are going to get the uh let's create our service and this service
will return us the project and the pagination for us so let's say constant uh this is going
to be the object so we're going to see our it get um all projects in workspace service
and we're going to pass in the workpace ID page size and page number so workspace ID
page size and page number so let's save that let's go to a service and let's create this
so inside the workspace not workspace service yeah weet service you're going to say export
constant uh get workspace get project and workspace service
then let's just say async space ID the
string so let me just say this and we're going to have our page size
number page number which is a number so we are going to uh
like let's say inside here so the first thing we going to do is to find all projects in workspace
so find step one find all project in workspace so let's get a total count so constant total [Music]
count model you find not find sorry count document so we going to count
it say workspace we going to pass in the workspace ID here so once we um save that so now we need
to also get um we need to skip here so skip we calculate the number of document to skip so we're
going to say page number minus one * page size item per page and this is the page so starting
from - 0 * the B size so we have one here and this is 10 so this should be 1 - 1 0 * um 10 so
if we if we move down here we're going to try to um pass in the skp inside our project model
and also the P size so let's say constant project is equals to A we project model on
find so workspace going to be workspace ID so we can find for
the project in workpace then we are going to say
skip this so we're going to Al set limit so limit is the P size and then we're going to
populate so let's poate created
by we're going to poate the ID for created
by name profile um p and we're going to omit the
password and then we're going to sort the descending
order so let me remove this here so we're going to sort by descending
order created minus one so once we done with that we need to also calculate the
total page so to calculate total page so we're going say total
page pages is going to be equals to we're going to M this and sell we're going to say the total
count divided by P size and we're going to round it off into number figure so once we done with
this we've gotten the skip total amount and the project then the total page we can return all to
our controller so let's return this and let's go into our controller and let's import this
here so uh we're going to um so let's get everything from object we have the project
[Music] pages and Skip so we're going to call our response here say
return response.
status HTTP status. okay I'm going say Jon I going to have our message here
so project F successfully we going to pass in our project and last we're going to pass
in pation so let's type in pation and inside here we're going to pass in total count page size page
number to Page Pages es [Music] skip you can also pass limit limit is still same as P size
so P side is still similar to the same with limit so we are
done with a get up project so let's import that in our
route update this and let's test this out so I'm going to create more
project so let me create
uh then me create more project get
here s this is
so and let me add an emoji for this
[Music]
so let me create
this so now let's try and get all um all and project so I'm going to
copy the uh workspace ID here and let me go to all
projects so this is it so let me replace this and let's set this
oh so I'm going to remove this here and we can see project workspace the
project um the workspace ID and all and let's fetch everything
here we can get two and we can see the P total count two B size 10
one total page one skip zero and limits 10 so if I pass in my page size and um and uh page number
here so we have page size of 10 page number of one so I can set this to uh let's say uh
one and we can see that this fetch only one
project for us so that count to P size one page page two so if I move this to
two and we can see we get font component so this is how it works so we set it back to P size to 10
and this to one so we done with that so let's go ahead and work on the next API which we are going
to is to get a single end point to get a single project in so to work on that we're going to
create the route here so below here we're going to say project route. get say project ID so this will
be project ID this your workspace and workspace ID so we can project by ID and work and workspace ID
controller so let's save that and let's create the endpoint let's create a controller so
let's go here and let's say export Conant let's SP this and let say async Handler
asnc and we're going to put in the uh let's call Arrow and I'm going to just copy
this so here we're going to get the workspace ID and also the uh the
project ID because we specify that in the um in the route if you look
at the route we have the ID for the project so I'm going to do that here
and you know we already have the project ID schema so I'm going to import that
from the validation if you go into the Elation you should see that we set it
here so we should also get the user ID let's just copy everything
here so once we copy that here we set this to to view only then
we can create our project service say how just get project by ID in workspace
service I'm going copy this and paste this
here and here we're going to pass in the workpace ID and project ID
and let's go ahead and create this service into
our project service so I'm going to close this and let's say export
constant let me fix this constant here we have async let's just call
the arrow function here and let's say works space ID which is string
project ID which is string
to so we are going to uh you're going to get the the workspace ID
and also the project ID inside the project and to find the project so
we're say constant project is going going to be equals to await object
model
that's find
one where ID is Project ID and workspace that's workspace
ID then we're going to select certain things we need Sayo name and description then if not project
you're going to dra an error saying project not found or does not belong to the specific
workspace so let's import not found exception unless if we're able to get the workspace we
are going to just return the workspace and let's go into our controller and import
this and inside our contr we going to return the
response here so let's return this response here and you should say
it's okay project F successfully and we passing the project so let's just import
this and let's try it out
so uh we're going to let's make sure our server is
running so I'm going to C everything yeah let me just get all all the project
here so let's wait for this to server to come up so
database is connected so let me let me get all the um projects
first so we have all the projects I'm going to get the ID for this
project unless go to single project so you can create that F that request and
I'm going to just remove all of what I did here before and we have the project
then let's go into all projects and let's get the workspace ID we go over to single
project so let me remove all
this let's go over single project and let's add this for the workspace ID
here so we have the project ID and the workspace ID and let's try and send this
and now we can get you got the um project project name emoji and description so that
is it so to work on is the project analytics so this will be tied to a single project we've done
the one for workspace where we calculate the total number of taxs for the entire
workspace now we going to bring that down to for a single project so we're going to create
um so let's create that
here we just out get ID workspace workspace ID similar to this end points here but we're going
to add in analytics here and we have controller here so I spaceace analytics um project analytics
controller so let's copy this and let's go over to our controller and let's um create this say export
constant async Handler um we get our
async and let's get the request and response
as we're going to get this all of this let me paste it
here and we're going to also get this we're going to create our um let's create a
service and this will be our wait get project analytic service
and we're going to pass in the project ID and the workspace
ID and here we're going to just get the analytics once we are done so let's copy this let's head
over to the service and let's create that export um constant and let's paste this
so just me justy
this so workspace project ID we can just simply just change that so it has the same
fure workpace project ID so workspace project ID then we are going to uh
inside here so let's um get the projects U find the projects by the project ID and if we able to
find this project and the project does not belong to this workspace we can show an error so we say
not project or project workspace string not equals to workspace string to string then we thr a new
exception saying that project not found or does not Bel on to this workspace we can see that here
then now we need to do what we did inside the workspace so if I go into my workspace service
or and go to analytics we can see that this is what we did so we're going to do the same
thing for for um the project so let's close this and go back to our project service so I'm going
to um let current dat then we're going to count the tax model so we' been able to see inside the
workspace controller we be able to not control our workspace service we a to see the approach
this approach of quering the database we can use the mongus uh mongus Agate aggregate to also do
that so I'm going to go into my project um my get project analys service and let's do constant tax
analytics and this is going to be equals to our so we are going to be using um
using mongos right so let's try this out us Mong aggate so say and say tax
model dot Aggregates and we're going to open a bracket here and we're going to first of all
get a match and this is we say March using this dollar sign you can see that here and there we're
going to say Bas we're going to find that base on the project ID so project you know inside the tax
model we descri project as some project ID should look at it project as project ID then we can set
project then we need to convert this project ID from our string to an object ID so we say new
mongus so let's import mongus do
types do objects ID
project
ID so we've convert this then we need to then we need so we're going to set up a pipeline which
is called um facet so facet is an aggregation stage in mongod that combine multiple aggregation
pipelines into one stage so we're going to do that faet will help us to combine multiple
aggregation so we're going to get equation for total tax overdue tax and completed tax in one
parall pipeline so um let's create let's do that here we've already done this now let's
just create this here and we're going to say this is going to be a call it foret and then PR open
this sh so the first agation we're going to do is a total tax so we're going to give it name total
tax here and this total tax we going to count the documents so we're going to set this here count
here and let's call this count so we are using the count operator from the aggregation from
the aggates here so so we've done for total count to count all tax that matches um inside this that
matches this project ID so now we need to get the over overdue so overdue is going to have multiple
F here we're going to say at Le here and we going to first of all use the March operator to get the
due date to make sure that due date so let's get new date and this is going to be the less than
current date then we going to you have multiple matches here we are going to also do for the
status and the status you're going to say we going to use the not equals so our tax St in
done so if it match this so it must match this to give us then once we
able to filter the match then we can count the document then let's use the count here
so open this and let's use the count operator to count the documents after this so you done
with this so lastly you're going to do for the completed so I'm going to just
uh completed here so for the completed we're going
to also use match match then I'm going to change this from don't and let's use
this so we've been able to um match uh try to should T down to match every TX
that has a status of them and then we count it so once we are done with this
we can then get tax analytics andless uh let's come down here and let's doore
analytics this is going to be equals to analytics and let's get the index
and then we can get the analytics
here and we can use so total tax we want say total tax
here total tax we're going to say analytics and do total tax which is this here and we're going
to get the index Z and get count yeah we're going to do that for overdue overdue TX to so let's just
duplicate this and paste it here so overdue tax to overdue tax is what we set here and we can
just get that and we're going to for the last one which is completed tax uh completed tax say
completed tax we going to get the count so once we are done with that we can just set our object here
so let's just uh let's just return
this let's return the analytics so we are done with this so let's go ahead and then
test this inside the controller let's import this from service and um we are going to run
the return return the response here so let's [Music] return status HTTP status do okay
I and we're going to just return both here project
analystics will sucessfully and analytics so let's import this
and get P analytics
controller so once we save that so make sure our server is running and let's test this out
so we're going to provide the uh ID project ID and workspace ID so I'm going to go over
to my end points here and let's wait for the server to connect to the data so server and
my database is connected so let's test this endpoint so I'm going to copy the project ID
and let's go straight to project analytics so I'm going to click on this to view the endpoint
here so I'm going to remove all all of these IDs here I pass here so I'm going to set project you
said project ID which we copied from single project and I'm going to copy the workspace
ID and let's go into project project analytics and let's replace this let's put the ID so this
is similar to and this project ID workspace project ID workspace workspace ID analytics
so we have that so let's try and send this so let me remove this let me send this and then we
should see so we have total tax Z overdue tax Z completed tax zero so we are going to come back
and test this once we when we implement the tax API so for now we're going to create the next um
API for our project which is the updated um API R so we're going to create the route here so I'm
going to create a pool request here so let's just bring the th here and let's say Project R putut
and we're going to set is to um ID project ID workspace and workspace ID and update and
let's call this um updates project controller so copy it and let's sorry copy it and let's
head over to project controller and let's export constant let's paste it here and async Handler
async and let's copy
this so for the put request we and for the update remember we are going to get the body and the
workspace ID so and the project ID so I'm going to copy that from the create and let's SP this here
I'm going to change this to update uh project schema if you go into up the project schema
remember we have set the schema already here so let's go ahead and let's also get the project
ID from theog [Music] programs so we're going to also get the
user so and we're going to also check if the user have access to uh
yeah so I'm going to let's just move this up here bring this body
down so here we're going to also get the check if the user is a member in
the workspace and also have the permission to edit uh project so I'm going to select
edit project so you can see edit project here and then let's create the work let's
create the service so going to say this to await um we're going to name this object
um update project service and we're going to pass in the workspace ID project ID and
body so we're going so let's create this update update project service inside the
project service so I'm going to cons I'm going to collapse this service here I'm going to just
say constant export constant and let's P this upd this project service is going to
space ID is going to string we have our project is going to be string and we have our
body so our body you can just get this from
here and let me just SC this put the arrow this here so we have
going to uh check the so let's D structure the body
here
name emoji and then
description then let's first of all check if the if we can find the project in that
uh the project ID and and also the workpace in the project model so let's say constant
project all say project model do find find [Music] one and we're going to pass in the
ID here project and going to also pass in the workspace workspace ID so if we could
not if we can if we could not find any of this any of the projects inside the project
model with the project ID we dra an exception not found exception saying project not found
does not belong to the specific workpace but if that we're going to uh let say
ifo let me let's open this here we can say if
emoi let's set project I'm going to just it like this and say project dooi equals too
then let's check for if update if name so we can update them like this and last we can save for
description and then we can save this and [Music] return and let's return the uh the
project so once we save that then let's go over to our control and let's import this
import the service and once you import the service let's get the project from
here and then let's return the
response so the response we taking project updated successfully and set
project so let's save that and going to rout and let's import the update project
controller let's save it as hopefully our server is running so let's test this
out so let's wait for this to uh to connect to database meanwhile I'm going to get the project
ID and from the project analytics so let's remove all this here and let me go into um project update
project so now let's uh so I have my update project here so let me put in the let's let's
go over to project analytics and let's copy the ID so I'm going to copy this and
project ID and updates I'm going to pass the project ID and this we're going to have the
workspace slash let's go to the analytics again and let's copy
the workspace ID here and let me pass that here and let's put
update so yeah for this project um the project is sales and this is
the description so I'm just going to copy the name I'm not going to change okay I can change
theoi if I want so let me ass uh [Music] Emoji I'm going to use a different Emoji
here so let me get see
Emoji so I specify I've change the from sales and say this is
updated so and let's try and submit this so we set the project ID so this is ending
from f13 and this should be it iPhone 3 at the end so let's click on let's cck on
send and then it is updated if you go over to get a
single project if I click on this we can see that this we change here see the
has changed and the disc has changed so that is it so lastly we're going to work on the late point
for the project so let's come to where we have here and let's create the uh route for that so
for the route it's going to be similar to put request but we're just going to change that to
delete and let me just break this like this
so this is going to be delete project
controller so we have ID workspace project ID workspace workspace id/
delete so let's copy the delete project controller and let's head over to our
controller and let's export Conant L and project controller and let's have async
Handler and let's just open this let's copy the request um and um the request
and response and let's s it here so we're going to also just copy only
P only the parents we need and let's also copy
this so we're going to change it from edit to delete
delete um project so delete
project so now let's create the service for this we say await delete roject
service and we going to pass in the workspace ID and project ID and if
this is successful we're going to just return the project deleted successfully so let's copy
delete project service and let's head over to service and let's create the service for this
so let's let me collapse this and let's say export constant delete project service asnc
so I'm just going to um this back let me just P the workspace ID and project ID here so then
we're going to also do the same thing we're going to find the project which from with
find the project that has your workspace ID and project ID so say project project model
find one ID project ID workspace workspace ID and we are going to do the same thing we did
in the update project here we're going to also say if if not found then we're going to throw
an except exception so if we could not find the project we're going to throw this exception here
then if we're able to find the project we can delete that here so and you should know that if
Noti that once we delete the project we need to delete all taxs aligned to that project that this
project is connected to so we say await tax modu delete manyu and we can have the
project project _
ID and let's just return projects here
okay so let's go ahead and import
this then let's go into our project route and let's import delete project controller and then
let's test this let's test the endpoint out let's make sure our server is running so let's wait for
the server to Conn conect to the so the server is connected to the database so let's test so
I'm going to uh copy let me um go into click on this menu here and let's click on delete
project so let's so for the delete project we're going to use the same ID so let's get the the ID
of the project so I'm going to copy it here let's say the ID we going to say work space
slash workspace ID so I'm going to get the workspace ID
here and let's let me delete this workspace so I'm going to now let me space the workspace ID
and let me write the delete not delete the workspace I want to write the delete in the
URL the Endo what we have here so once we said that then we should test this end points and
this should delete the project and that project we are going to use here is the sales project
we want to delete so let's delete that so I'm going to click on delete I see project deleted
successfully if you try to view if I try to view this same project again you should see project
not found does not belong to the specific space so error not found also if you try
to update this it should tell you the same thing not found so we are done with project end point
so let's go over and work on the tax endpoint so let's start to work on the tax endpoint
so I'm going to clear all everything in my so I'm going to clean everything here and inside
the SRC folder I'm going to go first into your route and let's create a tax route so say tax.
RTX so inside the tax. route we're going to get the router from Express so I'm going to close
this my terminal and let's import router from Express and let's also export this as default
here so the first uh rout we're going to create is the uh tax route do create post and let's SL
project project ID slw
space SL workpace ID and we just put
create so we're going to name this controller create tax
controller so we're going to create a controller so let's go ahead and create our tax controller
so inside the controller I'm going to click to create a file called tax controller TX
and let's say export constant go t controller and let's get our think
hand so we going to get our request so get a request from Express and also the response from
Express so now we're going to also set a validation for the tax if we go into our tax model
we should see that we have bunch of things we're going to pass to the body when creating a t we're
going to pass the title which is required description optional we have to pass the
project um ID which is going to belong to the workspace status so mainly we going to pass
the title description status priority assign to and create person can doe date so this is what
we're going to pass to um the tax request body from the from our client side so let's go into
our T controller and we're going to just create that so I'm going to for this body
equals to create T schema and let's go ahead and create the schema so inside the validation we're
going to create tax validation so let me let me open this folder and let's create tax validation
[Music] validation.
CS so inside the tax to validation we are going to check we're going
to create a reusable similar to what we did for workspace and and project so for
the so we're going to say export first for the create and update STX export
constant this is going to be equals to sorry I think export con we're going to call this um
rate tax [Music] schema and this is going to be equals to set sort object so make sure to import
sold at the top here object and let's open this so we're going to first of the title and we're going
to create a reusable title SCH so let's just copy this again and paste it here and let's call this
updates a t schema so we are going to create a Tas schema
here I the title schema so title schema is going to be Z string
minimum one maximum 255 then we going to also look for the description so description is
going to be optional so I'm going to just say Z string PR optional and let's pass description
here so description is been passed here then also pass description to the update
schema so the next one we're going to do in our list is the priority so in order
to do handle the power here we are going to have to create that so let's say export
constant
priority
schema this is greaten to be an in so say s [Music] in and we're going to open this and
let's convert this say object your values so this should be Val we're going to pass in the tax um
priority in know we're going to set this to as array or string we going to do Dots Dots Dots
string and they should stop the error so if you hover over en you should see or over priority
you see how is a list so we convert this and our values you can see the priority is the low minimum
and high medium and high so let's also do the same thing for status here and let's change this to
status and let's change this to tax status enough and now let's set
this priority and also the status
schema so save that then we
to Also let's copy this and put it here so now for the for the assigned
to so inside assign we're going to say No Label true and this is
optional so we say to not La so we can have assigned to schema Z
string trim minimum one notable and optional so we can pass this
here let's just pass this here so the last but not the least is the so is the due date so for the due
date we going to create a dday schema so let's just copy this
and let's implement the D schema so I'm going to do that here so due date is
exportant due dat schema it's going to be sord
string let me break this do [Music] frame that's optional
refine so we need to refine this because this is going to set form
we need we can also check if this is a valid dat we can do this per
value and we say um return if not so say [Music] return return not value is equals to not
and we're going to say dates
PS
Z so it's not equals to
all and distri is when a and sorry guys so I
made a mistake so not if we not this or not this then we should throw a message
here we going to say invalid date provide a valid one so if not value and if there
if not a date invalid for please provide a valid date string and then we are done with
this so last we are going to also uh also set the schema for tax ID so I
can put that below here so that's schema and the Z string Tri minimum of one so
we going to once we trying to do update remember we going to have to pass the ID
so let's save this and let's go into our controller and let's import the cre stack
schema and then let's get project schem project ID schema and let's passing the
request par project ID so I'm going to import this last we going to also bring in the project
the workspace ID so let's also bring the workspace so workpace ID schema repairs
the workspace ID is provided then we're going to bring in you get the [Music] user so we can
get the user here so now we going to also uh have also check the user is a member of the
workspace and also we are going to um check the user have a permission so let me just let import
permission from the in and let's import the get member rle in workspace we passing the user ID
the workspace ID and this is the r guide so let's import the r guide to guide our work our endpoint
so once you this now we need to say our service it's going to be equals to await the create Tax
Service is should take workspace ID project ID uh user ready and
body so let's go ahead and create the service
so we don't have our service Tax Service F created so let's create
that so say tax. service. CX let me close this and let's say export
constant I think
so um inside the tax service we are going to the let's get the
arguments here we're going workpace by the string
project project ID string user ID string and
body so but is going to be the ptle description priority and uh so going set
this so I think priority is optional we didn't set so I'm going to just remove priority and
Status here ICI to do dates and description is might optional so let's just structure this
on the
body so now let's find the project project is equals to AIT
Pro Mod do find find by ID you want to find the project I
then say we going to also do a check if if if not project and then or will
the workspace to string is not equals to workspace the workspace ID will pass to
string then this project does not belong to this um project or does not belong to this
workspace so let's save it like this so we able to find the project and to check
if the project if the project exist or the workpace in this project matches the workpace
here then if that is the case then we need to assign the user uh we need to also validate
that this assigned to is a user existing in our members mod model so we say if assigned
to going say constant
is [Music]
assigned us
member so we're going to say await member model
do
exist we're going to pass in the user ID we going to pass in assign to I pass in
the workspace ID so if not we going to throw an error saying this uh throw an error saying
assign user is not a member of this workpace so if not we're going to create our tax so a
constant tax is equals to new tax model and let's read it so we're going to pass in the
title [Music] description
priority we going to set priority or we going to set a default one from prority
in medium which medium is a default so we're going to also get the status
the status and then tax status to do will be the default tax assign to will be assign then
we have cre by will be the user id workpace id is going to be workpace ID which we pass then
project ID is going to be a project ID which we pass and last we're going to pass to Du
date so let's save that and now let's save the tax and let's return the
tax so once we are done with the create and points let's go ahead and um import it inside the
controller so then we're going to return so let's get the tax
here and then let's return the response here
here let's import HTP status so T sucessfully so let's test this let's go into our route and
let's import create TX controller then lastly inside the index to TX we are going to also
let me close this let's copy and paste this and change this to tax and let's change this to tax
rout so now can we can go on and test so let's look at server is running so
let's wait for our server to our database to
connect so database is connected so if you look at I already have set my tax I've
created uh request for all what I'm going to create like the create tax so for the create
tax let's going to cre I have some sample data have placed here like title test tax
work description medium stat to do assign to now and due date I set the date here so
we need to pass the project so let's go into our route and make sure we follow this so we have to
so this should be project not project so we need to pass in tax SL
project SL project ID so let's get project ID here so to get a project
ID we can go over to all project and let's get all
project from this workspace
I think our database database is not
connected so let me cancel this let me run this again so database
is connected let's try and test it again so I'm going to fetch all um
projects yeah so it has fetched all the projects so let's get the uh let's get
the project ID for font components and let's go to create stacks and
in create tax we're going to pass the project ID here and let's put
workspace let me SL workspace slash we're going to pass in the workspace
ID so I'm going to go to all workspace and all projects and let's just copy the workspace ID
which we specified here and let's pass it inside create workspace here and we're going to say SL
create and let's run this and let's see so we can see that
the project the tax was created here completely so so this is working fine
we can create a new more tax here I can just say uh uh let's say add add
team and to Buton
component so you can also do it for the we add so add team so we can set that to too and
medium so I'm going to click on we can also change this to a different let me go into my
tax and let's pick a different uh let's set this to
high let's prority to high and let's set this to let's say this to do so let's save
this and that is it so let's go over to check let's go over to our project and let's confirm
from our project analytics and let's see if this will work so currently we have two TX in this uh
if go to all projects the tax here is 51 I mean the projects the project ID is 51 the work why the
uh project so let me just get the project here and let's go
into analytics project analytics let me change this to uh this project ID and
let's also confirm the the workspace I'm going to copy the workspace ID
here now let's going to get analytics project analytics I'm going to remove this and let's
save this and let's try and run this and let's see so we can see total tax is two overdue tax is
two so this is because the reason why saying overdue tax is is true
is because we didn't set our date here is
2513 and the current date is not three so but if
you create a new Tas and set this to like 12 and say and let's say test
tax T new tax and if you send this sa and let's get this
you should see that we have total Tas three but overdue
Tas is two so this work so also if you go over to our workspace
analytics and let's try this
here oh this is not F so let me get the let me let's get the uh so inside the all project
let me get the workspace ID and then let me go into my workspace analytics and let
me replace this workspace here and let's send we should see we have three and two
great so we are done with this create so let's go ahead and walk on the update Endo
so I'm going to clear all this from here so let's work on the update endpoint so
I'm going to go into my tax and let me close this then here I'm going to set put to tax ID
project project ID workpace workspace ID and update so I'm going to call this update task
controller so let's go ahead and work on this inside a task controller so for the
task controller we're going to just let's collapse this and set export
constant we get our asnc
Handler and we're going to have a
sync so let me just quickly get the request and response here so this is
going to actually be the same thing so I'm going to just get everything from here so
let's just copy everything like this let's paste it here let's change create this to
update update um tax schema yeah we have the project ID the workspace ID and the
user ID and we pass it so let's change this from create to edit
tax so we've done this now we need to create a service so let's create service here so on
and say await update service and we're going to pass in the workpace
ID project ID ta
ID I'm going to pass in the body so let's go ahead and work on the service
for for the up tax so let's go into service and let me collapse
this export constant update Tax Service as
sync and let's get everything
here scroll down and let me let me set this up
let me P this so we're going to pass in the workspace okay this
is not going to be user ID this is going to be and
tax a tax ID so let me copy tax ID here and let me go into
my tax service let me paste this here so
so we we also forgot to pass in the tax ID here we didn't get the TX schema so I'm going to do
that here [Music] um so we can get a TX schema we've already specify the tax I schema already
in the validation so let's save this body here and let get the next so let's import
this so we got the body from update tax schema we passing the request body to validate the request
body now we get the ID because in the tax we are passing the tax ID that's right we passing
the tax ID so we need to get the tax ID here we get the tax ID we get the project ID and we get
the workspace ID here so once we get that and pass the TX ID here so once you are done with
providing a tax ID let's go over back to the tax service and let's um let's first of all check the
project and we're going to say project model to find
by ID and we're going to have project ID here going to say if not
project then we can show and
error so we are going to also um on this page we're going to also check uh if the project
if the project workspace um is not equals to the workspace ID then we can show that this
does not belong to this project here or does not belong to the workspace then we can also get a
taxal to
a tax model find ID I'm going to pass in the tax ID and we can do the same thing we did here
you can say if not stxs now we going to say uh tax do project to string is not equals to
project project
ID then we can change the message so I'm going to set this message here
I think I made a mistake here this should be so sorry I made
a mistake here this should be true you not found
reception so let's copy it and let's bring it here
and let's change the message from not found to not found does not belong to
this project so um once you've checked that we can just quickly update that so
updated ta is equals to AR T to find by and and by ID and update say tax
ID and let's structure the
body and let's set new to chose so it return you Corr the updated data
us then if if we're not able to update this we can
an exception say fail to update tax and then we can quickly return the tax the updated tax so you
can also skip this step and just use the updated tax to check if the if a tax exists but I want to
make sure that this tax belong to this project ID so you can handle this in your own way it's it's
up to you so let's just save this here and let's go back to into our controller and let's import
this so let's get the tax the updated tax me and we're going to repon the tax here
so let's say return response H be okay just in tax updated successfully unless
the tax so we are done with the update and point let's go over and import
this and we can [Music] test so we're going to test so the next so we can
test it let's go over to the tax I'm going to click here and let's go to tax update
so let's test it Postman so inside the route we have the tax um ID we need to provide tax ID so
I'm going to go into my create tax and let's get the tax okay so let me try create new tabs
here but let's just set this to high andless you so just type in anything here let me submit
this and I can get this the tax let's get tax idore ID here copy it and let's go to
update let's past here we get a project type in project project ID you can get
a project ID here to see the project ID here just copy the project ID for this
and last we have the
workspace workspace get a workspace ID here so I'm
just going to copy the workspace ID and let's add it here and let's sash
update so for this uh the title is second tax and second your tax I'm going to let's let's get a
title let's P the ti here so we can also change
this to do so I'm going to go to my tax and let's change this from to do to in
progress and let's call the second second tax
we can leave it like so let's try and save it and see if it
works so this is lo 8,000 API let's try and send
it and immediately uh we can see that the end point a sucessful response and we can
see second tax new and T new and our status has changed to in progress so so that that that is
great so the next Endo we're going to work on is to get all Endo so in our in our route we're
going to set the end point here so let's set the let's set a route we going say tax tax route.
get and to get this all tax you're going to just tax work space
SL workpace
ID oh so for the get all tax project here will be will be set to um request [Music] par similar
to other so user can fetch all tax on the workspace and see all tax on the workspace
and also fetch tax based on the project based on the project so instead of creating M two end
point to hand that we create a single unique single end point filter out all project and
filter Project based on the project ID been pass so let's just name this get all
controller get on tax
controller and let's go ahead and create the let's go ahead and create your controller so
I'm going to go into my task controller and so let's go come over here and let's
export constant so let me collapse this constant and let's Place get
all tax controller and this will be our we put our ASN hand here this say
async and let's go ahead and copy the request response and let's paste it here so for this
endpoints we are going to get the user ID and also the workspace ID which we specify
in the route so we're going to go over to our task controller let's get the user ID
and let's also get the workspace ID this is workspace ID and we're going to pass this to the
schammer so we going to use workspace ID schema and PS the request param workspace so now we are
going to get all the filters to use to filter the workspace so we're going to set this to constant
filters and this is going to be an object then we're going to filter by project
ID so this going to be a request so we don't need to validate this
because it's it might be optional or not so I'm going to say project
ID we're going to say this to as
string or
undefine so we have we conf that by status and Status here is going to be a list of
status you can f canate the database or all tax from multiple status so I'm going to say
status and yes status is going to be if available then we're going to the
request request qu do status I'm going to say as string then what we're going to do
let me break this down what we're going to do is to split split it by
comma or we say to
undefine so we have for priority
similar to what we did here just copy that and let's paste it here and let's change this to
Priority the same thing so we also have for assign to we can also F by multiple
user we just been assigned to so I'm going to also paste that here
so let's copy this um check here and make sure to get this priority and change this
to Priority here then assign to we change the require request assign to and change this to
assign to here so make sure everything is right so we don't have any issue so uh now we need to
get the keyword so we can also figure by we can square the database or you can call it search the
database for certain tax so I'm going to call this keyword and this is just going to be query request
query do keyword string the string or undefined lastly we can have we can fig that by due dates
there is it so we we been able to set up our filter get our filter then we can get our
pation so um pation is going to be page size and page number as we've done before
and the project endo so we get the page size we convert them to integer and set
a default to 10 page number page number this is going to be require query query
and also we're going to set for to one so now we need to also check if the user is a member
of this workspace being pass so we're going to get R and let's just set R guide to view
only so once that is done let's let me collapse this F let's create a
service you can say
um constant
results is equals to A
R get let's get all Tax
Service get all tax service and let's pass in
the workspace the workspace ID the filters and also the
pation so now let's go ahead and create this tax service so let's go into our tax service
and let me collapse
this export constant dark service
sync so yeah we're going to get the workspace ID string FS
for the fils we are going to we going to specify all of what we've passed in the
controller so we going to um get the project ID status and we can paste it here so a project
which is all all are optional so project ID string status is a list of string because
we have to split this here so I'm going to go back to my service and then priority assigned
to so make sure everything are the same here assign to keyword and due
dat your keyword and due dat so let's also get the
pation P
size number
H number is going to set number this one option because we set
a default so let's create a simple let's create a
query and this is going to be of type
record record or
string comma any so this is going to be equals to going to say workspace workspace uh not workspace
ID so tax we set tax model to workspace so we're going to put so we're going to cre
the tax model based on what we pass into this qu so since we going to say must to pass the
workspace ID we going to set it here then we're going to apply the filter by saying if filter
if you do project ID then we're going say query the project ID
project then filter by project then we're going to say if fter do
status and filter the status
length is greater than
zero ler than zero then we can set qu status and then we're going to create let's create the um say
in say filter the status
so let's copy this and paste it below and let's change this to
Priority b super
priority then let's also change the query status priority and then
priority here so we going to also do the same thing for for assign to
to assign
to let's say that to assign to and let's also set this to assign two here so only
this three is a list of list of string so now for the keyword we can say if filter do
keyword and filter keyword is not equals to undefine then we're going to create the
title we going to
use I see
and expression and the filter. keyword then we're going to give this
option I so this is a regular expression and then we are passing the filter. keyword to it then for
this is uh this operation operator is is part of the Reg expression to set the the query to to case
insensitive so we can filter any TX regarding the the um the title case sensitive or not so
this will help us to to fix that so let's um Also let's also fter for the due date fter the due date
and let's get query.
dates so let's we're going to say set this to equal set the operator of equals to new
date fut date du date then we are done with the futter so let's set up pation
so we going to say constant let structure the pation object which we
passed you're going to get the page
size page number now let's uh set up set the skip so going say skip this is going to be equals to
page number number minus one the page size then we are done with this now let's let's query
this so we're going to use promise or to do that because we're going to have to count the document
and also find it based on the F so so there a constant tax and you're going to get a total
tax soorry to account it's going to be equals to
await promise.
all and we're going to get our tax model to find
we going to pass in the query then we're going to set skip
limit to P
size the sort we're going to sort this to descending order created
ads then let's populate
let's poate assign
to so we going to get the ID name profile
picture we going to Omit or exclude the
password so we going to also
upate the
project with ID
emoji and the name so we are done with this so the last
one is to get the document count document and let's pass the query
so once we done with that so let now create let's now get the total Pages let's calculate
that so this is it total count divided by pay size and here let's return with
taxation going to pass in the P size page number
total total
counts to Pages can skip so this is it so let's
go ahead and import this inside the controller so make sure everything
is everything is okay so let's go ahead and import
that so I'm going to import it [Music] from tax service and let's just return
response. status HTP status. okay
Jon I'm going to say a message
tax fet successfully or tax F successfully then
we are just going to return let's just structure result
here okay we focus something
here yeah
so we are done with this we're going to try to go
and um test this so let's go over to TA rout and let's import this
controller and then let's PR this so let's test it I'm to my controller so
I can see all the fter I need to pass so let's go into all ta and
here inside the route uh we specify the workspace so let's put in the workspace
SL your workspace ID so I'm going to go into my update and let's get the workspace ID here and
let's past that and let's say all so if you try to let's say let's try and fetch all tax
so I think something is wrong
here inter C object ID for Value work space
ID okay let's let me check this
here so inside the service I think I found it issue so going to service and and let me drop
this down we should we should see I set this to find by ID so this is wrong it should be find that
was what causing the issue there so let's check this ter is running and it's connected to the
database so now let's test it out without the fter so I'm going to click on send and then we
can see all all the taxs with the [Music] pation so now let's filter this tax now so we're going
to filter by status in progress or status um to do I think that is it so let's let's put
status we can select uh to do
yeah if you click on
submit we should say to do to do and to do so we
can filter only you can see only tax that has to status are been filtered
here so likewise we can um add the in progress state
to here and if you click on send you should see everything back you should see in progress
and ref it to do I think all is high the priority High okay yeah we can find for
priority set this to should filter by medium
so let's send you see only one that is been fed here so we have to do we have
medium so we can just remove everything I can remove everything from
this this will set to status and parity so then we can have the let have the
project config by project IDR we have only one project think so so we're not going to
do that we're going to do by keyword and do dat so let's to for keyword and
we have to do so let me just do for keyword first so I'm going to search
for let's search for the
second let me set this small letter here and let's click Send and you can see that
we able to able to return the Tex with the that match the keyword so likewise
we can do for the due date so I'm going to uh copy the date here and let me paste it
here if I send it should give us the same
tax so that it so I'm going to just remove everything but the
keyword and we can see that those are three has due dates of the same date are been
F ta and T tax and second tax so that is it for the all tax so let's go ahead and work on the next
end point tax end point we're going to f we're going to work on the single getting the single
tax that is tax by ID so here I'm going to just get that here you should say tax ID which is set
ID project project ID workspace and workspace ID and this is you can name this get T by ID
controller and let's copy
that let's go over to our controller and let's create the Endo constant
async Handler and let say
async and let's copy the request
response so we're going to get the user ID let's get the user ID here
and also we're going to get this project and workspace from the query par we're going to
we going to validate that they they available then we should also just let's move on to get
the get member R in workspace so we check the user is a member in this workspace
then we can just set the permission we can guide this and set the permission to view
only so now let's go ahead and create let's go
ahead and create the service so this is going to be tax always get tax by
ID by ID service
so yeah let's pass this workspace ID ret ID tax
oh yeah we didn't get the tax ID so let me just think yeah that's
ID set to ID project ID and workspace ID so let's get the tax ID let's pass
it so let's go ahead and create a service so
I'm going to go into my service and let me collapse this export
constant I
syn we have a workspace ID set string
reget
ID project
ID I set that to string and tax ID set that to string so let just return
this so let's find this project and we need to check if
not project and if project workpace not match then we say project found does not belong to
this workspace so workspace string to string is not equals to workspace ID to two string
so then let's do constant tax we're going to fetch the tax the tax model ni to find by ID
as you find one that much ID that's ID workspace ID to workspace not workspace
ID workspace and then we're going to do project so project
ID and then we can populate
the assign
to so let's popular that and let's define the field we want ID
name think ID [Music] name and
profile picture let's omit
password so we done with that so let's resp tax so if this is found
if this is not found you say tax not found but if it's found you just say
return so let's head over to our controller and let's import
this so then let's read
let's the response here so that's fet and we just passing the tax so let's
go ahead and test this let's make sure to import that inside the tax
route so to test this I'm going to so let's go and select um single tax here and here we're going to
put provide the tax ID so I go to all tax and let me just F this let's fetch uh let's second
I'm going to copy this ID here go into my snle T and pass it then I'm going to let type in Project
slash and let's go to tax and let's get the project ID for that tax and we have our
workspace and let's go into T and let's just get the
workpace let's save that and let's try and run this send yeah you can see it's fetched the tax
for us so we are done with this so the last 10 points we're going to work on is for tax is the
delete tax point so let's create a route for that
so I'm going to create route at the top here and say tax r.
delete and this we will just get a tax
ID workspace on workspace ID let's set this to here so we going to name this delete
tax delete tax
controller so tax id workpace id and let's go ahead and create the
controller save this and let's go to [Music] controller and let's create this here export
constant asnc hand
so let's just complete
this let's get the user
ID uh then we are going to the workspace ID so we're going to pass that into our
workspace schema I'm going to pass in the request par workspace into the
workspace so to validate that then and last we need to get the tax ID
so so if gotten the tax ID with query. ID let's also get set to
Ru let's check for if the user is a member and let's set this BR this to El tax permission
so that let's I wait
delete delete tax controller sorry
service and let's pass in the workspace ID and tax ID here then we can return response to
status http status. okay [Music] Jon and let's write a
message
successfully so let's go ahead and create this delete Tax
Service so let me scroll down say export constant
think so I'm just going to this this and let me remove the
pro then we should get the tax here
constants constant tax is equals to A tax find one and
delete find one and delete to ID as
workpace workspace I
then if if not if this could be deleted if we could not delete this TXS then we know that
that's that's not found or does not Bel belong to this workspace so let
just return let just return like this so we are done with this let's go ahead and import
this save that and let's go to our route and let's import the tax delete T
controller so we are done with that so make sure the server server is
running so now server is connected to database so
let's close this and test it out so I'm going to select delete tax
here and here we're going to provide the tax ID so let's go
ahead and find let me find for the second tax and let's delete this
tax and let's WR workspace
so workspace ID so they should have the workspace ID here so I'm going to copy
that let's paste that here and then we're going to just say delete and
let's save this and let's try and send the request I see T if you try to fet this now
which should see that's not found server error so that means we even checking this in the
service tax by ID okay yeah that's not and this is wrong this should be um not found
exception so let's make sure that we we use our app error here so let me try it again
check it's connected I send this now you you see tax now so we are done with the tax endo and all
endpoint switch for the back end so now we so now let's go ahead and work on the client side
and connect this end points to the front end so let's go ahead and work on that so to to set up
the client side we going to create a folder here so I'm going to clear all this and let's create
a folder not inside the backend but outside so I'm going to create it I'm going to call this
client and then let's create a new terminal and once you've done that
let's C it into client so for the clients I've already created a startup template for
this um client project so I don't start creating the client from beginning so if you go over to
the G up which is in the link is going to be in the description it should it should be brought
to this page where you see main so what you have to do is to click on this and let's s
the branch so you can see stter screen Branch so we are going to clone for this because the
St screen branch is only the client and we using V for the client so I'm going to copy
a link here get link so let's go into our terminal let's clone this so we're going
to clone from the branch we're going toay the branch let me close this and this is called
stter the
screens we're going to paste the the giop URL and let's cck enter and this should clone this
so once that is done we can go into client and let's let's go ahead and copy all this I'm going
to copy all this and move them into the C so I've moved them into clients you can see that
the folder which we clone from GitHub is empty now so I'm going to delete make sure you've deleted
the folder so if you go into the client you should see you come into the package addressing
of I set up some packages here so all this RX UI is from Shanty UI so if you want to learn
how to use shant with it I have a video on that the link will be in the description so we also
install trans um we table we have AOS and um we have Emoji mat which we're going to use for
emoji and we have um no so I'm going to explain what no is no is simply similar to um use state
but handle it on the URL so you're going to see example of how that's works then we hook form re
D and Zord we use Zord here so um so let's go into the SLC folder and into the mainx um inside here
we're wrapping up with uh the not adapter and U the query and provider if you go into query
Provider from the Contex you should see how to set up Stander query which we going to use for the
API call in in vit so you can see how it is then inside the T we have knocked um adapter so this
is coming from the package so let's go into our terminal and install all of these packages so I'm
going to go into um my C let's do mpm install all of the dependency so now let's wait for this to
install so all of the dependency has install completely so then we can run
the server mpm rev and this will run the V server for us and we can see local 513
so if we try to access this on our browser we should see it should take us to the login
page so yeah you can see the UI we already have for the login page if I go into uh into the app
so let's go through this into the app. TX then we have the app router so I'm going to go into
app router then inside the app rout we have we're using the browser RT from RE then we
have this rout we also have the um rout for the art and we have the protected route and last we
have the catch all route for not found then inside the alt route this is the route that
handles the authentication so inside UT rout if you go into UT this is where we are going to um
check if the user is logging Weir the user to the dashboard if not set them back to the
um the login page so then the base layout is the layout for the aut rout so you can see that this
is just a simple business if you put background red 500 and you should see here should change
and this supposed to change think we have a color background color inside the page but we can also
add um ping here to five six now you can see that that's given in the height space here so let me
save that then inside the alt route part if you go into a route part this is where we specify all
the rout the sign in sign up and Google F so this is when Google call back for our client if Google
fail to if you fail to sign in with Google so inside this route here you can see um we have the
route part inside the common folder this is where we set all the parts the protected route that is
for the workspace tax member settings and project details and we have the invite URL part then we
import them inside the route we specify where the belong rotated rout rout and then base part
route so this is that so lastly for the we've seen the protected route too so we have the um if we go
into the protected route yeah this is where we are going to check this uh so I have some data
I commented here so let me remove that so we have the protected route here and this is where we're
going to check if the user is signed in then Outlet is just like moving to the to continue
the processing to this uh into this route it's going to move to the next route and this app
layout up layout is where we set the Side Bar and header the uh current workspace dialog create
I mean they create project dialog they create workspace dialogue and we have the art provider so
inside the art provider we have the context for o provider this is just the workspace ID and um just
uh a context an empty context use we used to R so we're going to work on this Contex to fetch the
current user and this is where we're going to use to pass it to to be able to get the current user
using the Endo current user so I think that is all for now and then the great workspace we're going
to look at this two later let's just focus on the let's focus on the login so I'm going to go into
my pages and let's go into all and we have the login Here sign in so the sign is already set up
with Z valid and we have hook for then we have our Google button this button so if you click inside
it's a reusable one we use it for both the login and the sign up if you click on sign up here it
should see create an account and this has the name email and password C on sign in you can see that
here so that is it so let's head over to where we connect our API so if we go down to our leave
folder and we should click on Aus client we set up our a c so if you watch my previous video on
video you should see how we set up and we set we create here we set with because we're using cookie
session and we set a base URL so we're going to set this up um and also we return your resp and we
check if this is equals to unauthorized and St is 41 then we return the user to the login we notice
that the end point the user is not the session has expired so from there we can go into API so after
setting up this we have API so API is where we set up the end point so we have the login motation
register motation log mation this is for current user and these are all the um for both project
and tax everything is quite empty here just set the function for we set the function but nothing
inside just we've done this for current user end point and if you go to uh guys basically so
Bas before already have the base there and lastly
uh for the hook we have some hooks here and this Hook is just dialog to dialog for create
dialog for create workspace we're going to look at that use permission is empty then
others is from then this is just to get the use workspace is just to get the ID from the
URL and this this is uh this is where we use we're going to use dark table filter so we're
going to use no which we WRA this if you look at this you can see no here and we use no to
set um they use States so this is just to set States status object and we look at that yeah
basically what I want to show is the API so for the API we're going to create some hook
here for the API so the use H is where we're going to call the current and you can see
we are calling the current get current query function and that is inside the API inside
Le folder so this is it so we're going to use that inside the context so let's first of all
call our endpoint to let's connect our endpoint to the sign in and sign up pages so I'll just
scroll down here let's set up first the let's connect our connect with with Google so before
we do that let's go into our EMV and make sure we set up we pass in our local 000 API yeah so then
if you done that let me clear the whole reg here and let's go into sign in I click into Google or
button so here we're going to so for the Google oos button we are not basically going to connect
the endpoint to the button but we are going to redirect the user to the endpoint so I'm
going to come inside this handle click you should see handle click here and if
e
e e
Click on any text or timestamp to jump to that moment in the video
Share:
Most transcripts ready in under 5 seconds
One-Click Copy125+ LanguagesSearch ContentJump to Timestamps
Paste YouTube URL
Enter any YouTube video link to get the full transcript
Transcript Extraction Form
Most transcripts ready in under 5 seconds
Get Our Chrome Extension
Get transcripts instantly without leaving YouTube. Install our Chrome extension for one-click access to any video's transcript directly on the watch page.