Tools Needed:
- Rider
- .net 8.0 sdk
- git
- Postman
- PostgreSQL
- PG admin
Dependencies: automapper Quartz
References:
PostgreSQL Man: ![[postgresql-17-A4.pdf]] ![[Pasted image 20241022045135.png]]
Project Template: ![[Pasted image 20241021181043.png]]
MVC Architecture: ![[Pasted image 20241021181959.png]]
Migrations:
dotnet ef migrations add InitialMigration --project Rosario_Backend.DAL --startup-project Rosario_Backend.API
Change "InitialMigration" to whatever name needed.
dotnet ef database update --project Rosario_Backend.DAL --startup-project Rosario_Backend.API
Access token is short lived - 10 mins expiry Refresh Token is long lived - 2 days
both are stored on client side
if refresh token is expired user session gets expired and user need to login again.
easy way is to store refresh token to database and set up a job to clean expired refresh token.
add UserRefreshToken in DAL ![[Pasted image 20241112132053.png]]![[Pasted image 20241112132128.png]] ![[Pasted image 20241112132256.png]]
Logout: remove refresh token from db; ![[Pasted image 20241112132352.png]]
Change GenerateToken to GenerateAccessToken;
and
![[Pasted image 20241112132652.png]]
either like this ![[Pasted image 20241112132920.png]] or just like accesstoken jwt
Also check token expiry is wokring or not.
TODO:
Implement Login,Register,Menu Webpages just as in the images
fix access token expiry ( when i refresh token, i am still able to get profile using the first access token aswell as the new access token).
blacklist token is working correctly when logging out token is getting blacklisted as intended.
In UserService.cs, i have duplicate user existence checks:
if (await _context.Users.AnyAsync(u => u.Email == request.Email))
{
throw new BadRequestException("Email already registered");
}
This check could be replaced by using UserManager.FindByEmailAsync since Identity already handles unique email constraints. - DONE
- Consider adding mapping for Rating calculation in MappingProfile.cs:
CreateMap<Dish, DishDto>()
.ForMember(dest => dest.Rating,
opt => opt.MapFrom(src => src.Ratings.Any()
? src.Ratings.Average(r => r.Value)
: 0));
- Sorting in DishService:
The rating sorting might not work as expected:
"rating_asc" => query.OrderBy(d => d.Ratings),
"rating_desc" => query.OrderByDescending(d => d.Ratings),
Consider changing to:
"rating_asc" => query.OrderBy(d => d.Ratings.Any() ? d.Ratings.Average(r => r.Value) : 0),
"rating_desc" => query.OrderByDescending(d => d.Ratings.Any() ? d.Ratings.Average(r => r.Value) : 0),
![[Pasted image 20241113040053.png]]
To-Fix:
- when a user rates dishes the rating is not shown at the dish's page : Fixed ✅