Spaces:
Sleeping
Sleeping
Yuyuqt commited on
Commit ·
da13799
1
Parent(s): 861f0db
add: change userid to guid and small fixes
Browse files- Backend/Backend.csproj +1 -1
- Backend/Features/Auth/AuthService.cs +4 -3
- Backend/Features/Books/BookService.cs +4 -3
- Backend/Features/Borrowing/BorrowingController.cs +4 -4
- Backend/Features/Borrowing/BorrowingModels.cs +2 -2
- Backend/Features/Borrowing/BorrowingService.cs +12 -11
- Backend/Features/Categories/CategoryService.cs +4 -3
- Backend/Features/Loyalty/LoyaltyController.cs +1 -1
- Backend/Features/Subscriptions/SubscriptionController.cs +4 -4
- Backend/Features/Subscriptions/SubscriptionModels.cs +3 -3
- Backend/Features/Subscriptions/SubscriptionService.cs +12 -11
- Backend/Features/Users/UserController.cs +4 -4
- Backend/Features/Users/UserService.cs +13 -12
- Backend/Program.cs +3 -2
- Database/Models/Wishlist.cs +0 -17
- Database/add_reward_id_to_memberships.sql +0 -14
- Database/db.sql +0 -112
- Database/seed_data.sql +0 -86
- DbConnect/Class1.cs +7 -0
- Database/Models/LibraryManagementContext.cs → DbConnect/Data/AppDbContext.cs +20 -28
- Database/Database.csproj → DbConnect/DbConnect.csproj +0 -0
- {Database/Models → DbConnect/Entities}/Book.cs +7 -7
- {Database/Models → DbConnect/Entities}/Borrowing.cs +3 -3
- {Database/Models → DbConnect/Entities}/Category.cs +1 -1
- {Database/Models → DbConnect/Entities}/Membership.cs +3 -2
- {Database/Models → DbConnect/Entities}/User.cs +2 -4
- {Database/Models → DbConnect/Entities}/UserSubscription.cs +7 -3
- Frontend/Controllers/BorrowingsController.cs +2 -2
- Frontend/Controllers/MembersController.cs +6 -6
- Frontend/Models/Dtos/LibraryDtos.cs +6 -6
- Frontend/Services/LibraryApiClient.cs +7 -7
- LibraryManagement.slnx +1 -1
Backend/Backend.csproj
CHANGED
|
@@ -14,7 +14,7 @@
|
|
| 14 |
</ItemGroup>
|
| 15 |
|
| 16 |
<ItemGroup>
|
| 17 |
-
<ProjectReference Include="..\
|
| 18 |
</ItemGroup>
|
| 19 |
|
| 20 |
</Project>
|
|
|
|
| 14 |
</ItemGroup>
|
| 15 |
|
| 16 |
<ItemGroup>
|
| 17 |
+
<ProjectReference Include="..\DbConnect\DbConnect.csproj" />
|
| 18 |
</ItemGroup>
|
| 19 |
|
| 20 |
</Project>
|
Backend/Features/Auth/AuthService.cs
CHANGED
|
@@ -1,4 +1,5 @@
|
|
| 1 |
-
using
|
|
|
|
| 2 |
using Microsoft.EntityFrameworkCore;
|
| 3 |
using Microsoft.IdentityModel.Tokens;
|
| 4 |
using System.IdentityModel.Tokens.Jwt;
|
|
@@ -18,12 +19,12 @@ namespace Backend.Features.Auth
|
|
| 18 |
|
| 19 |
public class AuthService : IAuthService
|
| 20 |
{
|
| 21 |
-
private readonly
|
| 22 |
private readonly IConfiguration _configuration;
|
| 23 |
private readonly ISubscriptionService _subscriptionService;
|
| 24 |
private readonly ILoyaltyService _loyaltyService;
|
| 25 |
|
| 26 |
-
public AuthService(
|
| 27 |
{
|
| 28 |
_context = context;
|
| 29 |
_configuration = configuration;
|
|
|
|
| 1 |
+
using DbConnect.Data;
|
| 2 |
+
using DbConnect.Entities;
|
| 3 |
using Microsoft.EntityFrameworkCore;
|
| 4 |
using Microsoft.IdentityModel.Tokens;
|
| 5 |
using System.IdentityModel.Tokens.Jwt;
|
|
|
|
| 19 |
|
| 20 |
public class AuthService : IAuthService
|
| 21 |
{
|
| 22 |
+
private readonly AppDbContext _context;
|
| 23 |
private readonly IConfiguration _configuration;
|
| 24 |
private readonly ISubscriptionService _subscriptionService;
|
| 25 |
private readonly ILoyaltyService _loyaltyService;
|
| 26 |
|
| 27 |
+
public AuthService(AppDbContext context, IConfiguration configuration, ISubscriptionService subscriptionService, ILoyaltyService loyaltyService)
|
| 28 |
{
|
| 29 |
_context = context;
|
| 30 |
_configuration = configuration;
|
Backend/Features/Books/BookService.cs
CHANGED
|
@@ -1,4 +1,5 @@
|
|
| 1 |
-
using
|
|
|
|
| 2 |
using Microsoft.EntityFrameworkCore;
|
| 3 |
|
| 4 |
namespace Backend.Features.Books
|
|
@@ -14,9 +15,9 @@ namespace Backend.Features.Books
|
|
| 14 |
|
| 15 |
public class BookService : IBookService
|
| 16 |
{
|
| 17 |
-
private readonly
|
| 18 |
|
| 19 |
-
public BookService(
|
| 20 |
{
|
| 21 |
_context = context;
|
| 22 |
}
|
|
|
|
| 1 |
+
using DbConnect.Data;
|
| 2 |
+
using DbConnect.Entities;
|
| 3 |
using Microsoft.EntityFrameworkCore;
|
| 4 |
|
| 5 |
namespace Backend.Features.Books
|
|
|
|
| 15 |
|
| 16 |
public class BookService : IBookService
|
| 17 |
{
|
| 18 |
+
private readonly AppDbContext _context;
|
| 19 |
|
| 20 |
+
public BookService(AppDbContext context)
|
| 21 |
{
|
| 22 |
_context = context;
|
| 23 |
}
|
Backend/Features/Borrowing/BorrowingController.cs
CHANGED
|
@@ -24,7 +24,7 @@ namespace Backend.Features.Borrowings
|
|
| 24 |
var userIdStr = User.FindFirstValue(ClaimTypes.NameIdentifier);
|
| 25 |
if (string.IsNullOrEmpty(userIdStr)) return Unauthorized();
|
| 26 |
|
| 27 |
-
var userId =
|
| 28 |
var borrowing = await _borrowingService.BorrowBookAsync(userId, request.BookId);
|
| 29 |
return Ok(borrowing);
|
| 30 |
}
|
|
@@ -36,7 +36,7 @@ namespace Backend.Features.Borrowings
|
|
| 36 |
|
| 37 |
[HttpPost("return-request/{id}")]
|
| 38 |
[Authorize]
|
| 39 |
-
public async Task<ActionResult<BorrowingDto>> RequestReturn(
|
| 40 |
{
|
| 41 |
try
|
| 42 |
{
|
|
@@ -51,7 +51,7 @@ namespace Backend.Features.Borrowings
|
|
| 51 |
|
| 52 |
[HttpPost("return/{id}")]
|
| 53 |
[Authorize(Roles = "Librarian")]
|
| 54 |
-
public async Task<ActionResult<BorrowingDto>> ReturnBook(
|
| 55 |
{
|
| 56 |
try
|
| 57 |
{
|
|
@@ -71,7 +71,7 @@ namespace Backend.Features.Borrowings
|
|
| 71 |
var userIdStr = User.FindFirstValue(ClaimTypes.NameIdentifier);
|
| 72 |
if (string.IsNullOrEmpty(userIdStr)) return Unauthorized();
|
| 73 |
|
| 74 |
-
var userId =
|
| 75 |
var borrowings = await _borrowingService.GetUserBorrowingsAsync(userId);
|
| 76 |
return Ok(borrowings);
|
| 77 |
}
|
|
|
|
| 24 |
var userIdStr = User.FindFirstValue(ClaimTypes.NameIdentifier);
|
| 25 |
if (string.IsNullOrEmpty(userIdStr)) return Unauthorized();
|
| 26 |
|
| 27 |
+
var userId = Guid.Parse(userIdStr);
|
| 28 |
var borrowing = await _borrowingService.BorrowBookAsync(userId, request.BookId);
|
| 29 |
return Ok(borrowing);
|
| 30 |
}
|
|
|
|
| 36 |
|
| 37 |
[HttpPost("return-request/{id}")]
|
| 38 |
[Authorize]
|
| 39 |
+
public async Task<ActionResult<BorrowingDto>> RequestReturn(Guid id)
|
| 40 |
{
|
| 41 |
try
|
| 42 |
{
|
|
|
|
| 51 |
|
| 52 |
[HttpPost("return/{id}")]
|
| 53 |
[Authorize(Roles = "Librarian")]
|
| 54 |
+
public async Task<ActionResult<BorrowingDto>> ReturnBook(Guid id)
|
| 55 |
{
|
| 56 |
try
|
| 57 |
{
|
|
|
|
| 71 |
var userIdStr = User.FindFirstValue(ClaimTypes.NameIdentifier);
|
| 72 |
if (string.IsNullOrEmpty(userIdStr)) return Unauthorized();
|
| 73 |
|
| 74 |
+
var userId = Guid.Parse(userIdStr);
|
| 75 |
var borrowings = await _borrowingService.GetUserBorrowingsAsync(userId);
|
| 76 |
return Ok(borrowings);
|
| 77 |
}
|
Backend/Features/Borrowing/BorrowingModels.cs
CHANGED
|
@@ -4,8 +4,8 @@ namespace Backend.Features.Borrowings
|
|
| 4 |
{
|
| 5 |
public class BorrowingDto
|
| 6 |
{
|
| 7 |
-
public
|
| 8 |
-
public
|
| 9 |
public string UserEmail { get; set; } = string.Empty;
|
| 10 |
public int BookId { get; set; }
|
| 11 |
public string BookTitle { get; set; } = string.Empty;
|
|
|
|
| 4 |
{
|
| 5 |
public class BorrowingDto
|
| 6 |
{
|
| 7 |
+
public Guid Id { get; set; }
|
| 8 |
+
public Guid UserId { get; set; }
|
| 9 |
public string UserEmail { get; set; } = string.Empty;
|
| 10 |
public int BookId { get; set; }
|
| 11 |
public string BookTitle { get; set; } = string.Empty;
|
Backend/Features/Borrowing/BorrowingService.cs
CHANGED
|
@@ -1,4 +1,5 @@
|
|
| 1 |
-
using
|
|
|
|
| 2 |
using Microsoft.EntityFrameworkCore;
|
| 3 |
using Backend.Features.Loyalty;
|
| 4 |
|
|
@@ -6,26 +7,26 @@ namespace Backend.Features.Borrowings
|
|
| 6 |
{
|
| 7 |
public interface IBorrowingService
|
| 8 |
{
|
| 9 |
-
Task<BorrowingDto> BorrowBookAsync(
|
| 10 |
-
Task<BorrowingDto> RequestReturnAsync(
|
| 11 |
-
Task<BorrowingDto> ReturnBookAsync(
|
| 12 |
-
Task<IEnumerable<BorrowingDto>> GetUserBorrowingsAsync(
|
| 13 |
Task<IEnumerable<BorrowingDto>> GetAllBorrowingsAsync();
|
| 14 |
}
|
| 15 |
|
| 16 |
public class BorrowingService : IBorrowingService
|
| 17 |
{
|
| 18 |
-
private readonly
|
| 19 |
private readonly ILoyaltyService _loyaltyService;
|
| 20 |
private const decimal FinePerDay = 500;
|
| 21 |
|
| 22 |
-
public BorrowingService(
|
| 23 |
{
|
| 24 |
_context = context;
|
| 25 |
_loyaltyService = loyaltyService;
|
| 26 |
}
|
| 27 |
|
| 28 |
-
public async Task<BorrowingDto> BorrowBookAsync(
|
| 29 |
{
|
| 30 |
// 1. Check for Active Membership
|
| 31 |
var subscription = await _context.UserSubscriptions
|
|
@@ -95,7 +96,7 @@ namespace Backend.Features.Borrowings
|
|
| 95 |
return MapToDto(borrowing);
|
| 96 |
}
|
| 97 |
|
| 98 |
-
public async Task<BorrowingDto> RequestReturnAsync(
|
| 99 |
{
|
| 100 |
var borrowing = await _context.Borrowings
|
| 101 |
.Include(b => b.Book)
|
|
@@ -110,7 +111,7 @@ namespace Backend.Features.Borrowings
|
|
| 110 |
return MapToDto(borrowing);
|
| 111 |
}
|
| 112 |
|
| 113 |
-
public async Task<BorrowingDto> ReturnBookAsync(
|
| 114 |
{
|
| 115 |
var borrowing = await _context.Borrowings
|
| 116 |
.Include(b => b.Book)
|
|
@@ -159,7 +160,7 @@ namespace Backend.Features.Borrowings
|
|
| 159 |
return MapToDto(borrowing);
|
| 160 |
}
|
| 161 |
|
| 162 |
-
public async Task<IEnumerable<BorrowingDto>> GetUserBorrowingsAsync(
|
| 163 |
{
|
| 164 |
var borrowings = await _context.Borrowings
|
| 165 |
.Include(b => b.Book)
|
|
|
|
| 1 |
+
using DbConnect.Data;
|
| 2 |
+
using DbConnect.Entities;
|
| 3 |
using Microsoft.EntityFrameworkCore;
|
| 4 |
using Backend.Features.Loyalty;
|
| 5 |
|
|
|
|
| 7 |
{
|
| 8 |
public interface IBorrowingService
|
| 9 |
{
|
| 10 |
+
Task<BorrowingDto> BorrowBookAsync(Guid userId, int bookId);
|
| 11 |
+
Task<BorrowingDto> RequestReturnAsync(Guid borrowingId);
|
| 12 |
+
Task<BorrowingDto> ReturnBookAsync(Guid borrowingId);
|
| 13 |
+
Task<IEnumerable<BorrowingDto>> GetUserBorrowingsAsync(Guid userId);
|
| 14 |
Task<IEnumerable<BorrowingDto>> GetAllBorrowingsAsync();
|
| 15 |
}
|
| 16 |
|
| 17 |
public class BorrowingService : IBorrowingService
|
| 18 |
{
|
| 19 |
+
private readonly AppDbContext _context;
|
| 20 |
private readonly ILoyaltyService _loyaltyService;
|
| 21 |
private const decimal FinePerDay = 500;
|
| 22 |
|
| 23 |
+
public BorrowingService(AppDbContext context, ILoyaltyService loyaltyService)
|
| 24 |
{
|
| 25 |
_context = context;
|
| 26 |
_loyaltyService = loyaltyService;
|
| 27 |
}
|
| 28 |
|
| 29 |
+
public async Task<BorrowingDto> BorrowBookAsync(Guid userId, int bookId)
|
| 30 |
{
|
| 31 |
// 1. Check for Active Membership
|
| 32 |
var subscription = await _context.UserSubscriptions
|
|
|
|
| 96 |
return MapToDto(borrowing);
|
| 97 |
}
|
| 98 |
|
| 99 |
+
public async Task<BorrowingDto> RequestReturnAsync(Guid borrowingId)
|
| 100 |
{
|
| 101 |
var borrowing = await _context.Borrowings
|
| 102 |
.Include(b => b.Book)
|
|
|
|
| 111 |
return MapToDto(borrowing);
|
| 112 |
}
|
| 113 |
|
| 114 |
+
public async Task<BorrowingDto> ReturnBookAsync(Guid borrowingId)
|
| 115 |
{
|
| 116 |
var borrowing = await _context.Borrowings
|
| 117 |
.Include(b => b.Book)
|
|
|
|
| 160 |
return MapToDto(borrowing);
|
| 161 |
}
|
| 162 |
|
| 163 |
+
public async Task<IEnumerable<BorrowingDto>> GetUserBorrowingsAsync(Guid userId)
|
| 164 |
{
|
| 165 |
var borrowings = await _context.Borrowings
|
| 166 |
.Include(b => b.Book)
|
Backend/Features/Categories/CategoryService.cs
CHANGED
|
@@ -1,4 +1,5 @@
|
|
| 1 |
-
using
|
|
|
|
| 2 |
using Microsoft.EntityFrameworkCore;
|
| 3 |
|
| 4 |
namespace Backend.Features.Categories
|
|
@@ -13,9 +14,9 @@ namespace Backend.Features.Categories
|
|
| 13 |
|
| 14 |
public class CategoryService : ICategoryService
|
| 15 |
{
|
| 16 |
-
private readonly
|
| 17 |
|
| 18 |
-
public CategoryService(
|
| 19 |
{
|
| 20 |
_context = context;
|
| 21 |
}
|
|
|
|
| 1 |
+
using DbConnect.Data;
|
| 2 |
+
using DbConnect.Entities;
|
| 3 |
using Microsoft.EntityFrameworkCore;
|
| 4 |
|
| 5 |
namespace Backend.Features.Categories
|
|
|
|
| 14 |
|
| 15 |
public class CategoryService : ICategoryService
|
| 16 |
{
|
| 17 |
+
private readonly AppDbContext _context;
|
| 18 |
|
| 19 |
+
public CategoryService(AppDbContext context)
|
| 20 |
{
|
| 21 |
_context = context;
|
| 22 |
}
|
Backend/Features/Loyalty/LoyaltyController.cs
CHANGED
|
@@ -101,7 +101,7 @@ namespace Backend.Features.Loyalty
|
|
| 101 |
|
| 102 |
// 3. side effect: Grant membership in the library system
|
| 103 |
bool membershipGranted = false;
|
| 104 |
-
if (
|
| 105 |
{
|
| 106 |
System.Diagnostics.Debug.WriteLine($"Fulfilling redemption {id} for user {userId}. RewardId: '{redemption.RewardId}', RewardName: '{redemption.RewardName}'");
|
| 107 |
membershipGranted = await _subscriptionService.HandleLoyaltyRedemptionAsync(userId, redemption.RewardId, redemption.RewardName, redemption.Id);
|
|
|
|
| 101 |
|
| 102 |
// 3. side effect: Grant membership in the library system
|
| 103 |
bool membershipGranted = false;
|
| 104 |
+
if (Guid.TryParse(redemption.ExternalUserId?.Trim(), out Guid userId))
|
| 105 |
{
|
| 106 |
System.Diagnostics.Debug.WriteLine($"Fulfilling redemption {id} for user {userId}. RewardId: '{redemption.RewardId}', RewardName: '{redemption.RewardName}'");
|
| 107 |
membershipGranted = await _subscriptionService.HandleLoyaltyRedemptionAsync(userId, redemption.RewardId, redemption.RewardName, redemption.Id);
|
Backend/Features/Subscriptions/SubscriptionController.cs
CHANGED
|
@@ -29,7 +29,7 @@ namespace Backend.Features.Subscriptions
|
|
| 29 |
var userIdStr = User.FindFirstValue(ClaimTypes.NameIdentifier);
|
| 30 |
if (string.IsNullOrEmpty(userIdStr)) return Unauthorized();
|
| 31 |
|
| 32 |
-
var userId =
|
| 33 |
var subscription = await _subscriptionService.GetUserSubscriptionAsync(userId);
|
| 34 |
|
| 35 |
if (subscription == null) return NotFound(new { message = "No active subscription found." });
|
|
@@ -44,7 +44,7 @@ namespace Backend.Features.Subscriptions
|
|
| 44 |
var userIdStr = User.FindFirstValue(ClaimTypes.NameIdentifier);
|
| 45 |
if (string.IsNullOrEmpty(userIdStr)) return Unauthorized();
|
| 46 |
|
| 47 |
-
var userId =
|
| 48 |
var subscriptions = await _subscriptionService.GetUserAllSubscriptionsAsync(userId);
|
| 49 |
return Ok(subscriptions);
|
| 50 |
}
|
|
@@ -58,7 +58,7 @@ namespace Backend.Features.Subscriptions
|
|
| 58 |
var userIdStr = User.FindFirstValue(ClaimTypes.NameIdentifier);
|
| 59 |
if (string.IsNullOrEmpty(userIdStr)) return Unauthorized();
|
| 60 |
|
| 61 |
-
var userId =
|
| 62 |
var subscription = await _subscriptionService.SubscribeUserAsync(userId, request.MembershipId);
|
| 63 |
return Ok(subscription);
|
| 64 |
}
|
|
@@ -70,7 +70,7 @@ namespace Backend.Features.Subscriptions
|
|
| 70 |
|
| 71 |
[HttpGet("subscriptions/user/{userId}")]
|
| 72 |
[Authorize(Roles = "Librarian")]
|
| 73 |
-
public async Task<ActionResult<SubscriptionDto>> GetUserSubscription(
|
| 74 |
{
|
| 75 |
var subscription = await _subscriptionService.GetUserSubscriptionAsync(userId);
|
| 76 |
if (subscription == null) return NotFound(new { message = "No active subscription found." });
|
|
|
|
| 29 |
var userIdStr = User.FindFirstValue(ClaimTypes.NameIdentifier);
|
| 30 |
if (string.IsNullOrEmpty(userIdStr)) return Unauthorized();
|
| 31 |
|
| 32 |
+
var userId = Guid.Parse(userIdStr);
|
| 33 |
var subscription = await _subscriptionService.GetUserSubscriptionAsync(userId);
|
| 34 |
|
| 35 |
if (subscription == null) return NotFound(new { message = "No active subscription found." });
|
|
|
|
| 44 |
var userIdStr = User.FindFirstValue(ClaimTypes.NameIdentifier);
|
| 45 |
if (string.IsNullOrEmpty(userIdStr)) return Unauthorized();
|
| 46 |
|
| 47 |
+
var userId = Guid.Parse(userIdStr);
|
| 48 |
var subscriptions = await _subscriptionService.GetUserAllSubscriptionsAsync(userId);
|
| 49 |
return Ok(subscriptions);
|
| 50 |
}
|
|
|
|
| 58 |
var userIdStr = User.FindFirstValue(ClaimTypes.NameIdentifier);
|
| 59 |
if (string.IsNullOrEmpty(userIdStr)) return Unauthorized();
|
| 60 |
|
| 61 |
+
var userId = Guid.Parse(userIdStr);
|
| 62 |
var subscription = await _subscriptionService.SubscribeUserAsync(userId, request.MembershipId);
|
| 63 |
return Ok(subscription);
|
| 64 |
}
|
|
|
|
| 70 |
|
| 71 |
[HttpGet("subscriptions/user/{userId}")]
|
| 72 |
[Authorize(Roles = "Librarian")]
|
| 73 |
+
public async Task<ActionResult<SubscriptionDto>> GetUserSubscription(Guid userId)
|
| 74 |
{
|
| 75 |
var subscription = await _subscriptionService.GetUserSubscriptionAsync(userId);
|
| 76 |
if (subscription == null) return NotFound(new { message = "No active subscription found." });
|
Backend/Features/Subscriptions/SubscriptionModels.cs
CHANGED
|
@@ -16,8 +16,8 @@ namespace Backend.Features.Subscriptions
|
|
| 16 |
|
| 17 |
public class SubscriptionDto
|
| 18 |
{
|
| 19 |
-
public
|
| 20 |
-
public
|
| 21 |
public int MembershipId { get; set; }
|
| 22 |
public string MembershipType { get; set; } = string.Empty;
|
| 23 |
public string UserEmail { get; set; } = string.Empty;
|
|
@@ -35,7 +35,7 @@ namespace Backend.Features.Subscriptions
|
|
| 35 |
|
| 36 |
public class AdminSubscribeRequest
|
| 37 |
{
|
| 38 |
-
public
|
| 39 |
public int MembershipId { get; set; }
|
| 40 |
}
|
| 41 |
}
|
|
|
|
| 16 |
|
| 17 |
public class SubscriptionDto
|
| 18 |
{
|
| 19 |
+
public Guid Id { get; set; }
|
| 20 |
+
public Guid UserId { get; set; }
|
| 21 |
public int MembershipId { get; set; }
|
| 22 |
public string MembershipType { get; set; } = string.Empty;
|
| 23 |
public string UserEmail { get; set; } = string.Empty;
|
|
|
|
| 35 |
|
| 36 |
public class AdminSubscribeRequest
|
| 37 |
{
|
| 38 |
+
public Guid UserId { get; set; }
|
| 39 |
public int MembershipId { get; set; }
|
| 40 |
}
|
| 41 |
}
|
Backend/Features/Subscriptions/SubscriptionService.cs
CHANGED
|
@@ -1,4 +1,5 @@
|
|
| 1 |
-
using
|
|
|
|
| 2 |
using Microsoft.EntityFrameworkCore;
|
| 3 |
using Backend.Features.Loyalty;
|
| 4 |
|
|
@@ -7,19 +8,19 @@ namespace Backend.Features.Subscriptions
|
|
| 7 |
public interface ISubscriptionService
|
| 8 |
{
|
| 9 |
Task<IEnumerable<MembershipDto>> GetMembershipsAsync();
|
| 10 |
-
Task<SubscriptionDto?> GetUserSubscriptionAsync(
|
| 11 |
-
Task<IEnumerable<SubscriptionDto>> GetUserAllSubscriptionsAsync(
|
| 12 |
-
Task<bool> HandleLoyaltyRedemptionAsync(
|
| 13 |
-
Task<SubscriptionDto> SubscribeUserAsync(
|
| 14 |
Task<IEnumerable<SubscriptionDto>> GetAllSubscriptionsAsync();
|
| 15 |
}
|
| 16 |
|
| 17 |
public class SubscriptionService : ISubscriptionService
|
| 18 |
{
|
| 19 |
-
private readonly
|
| 20 |
private readonly ILoyaltyService _loyaltyService;
|
| 21 |
|
| 22 |
-
public SubscriptionService(
|
| 23 |
{
|
| 24 |
_context = context;
|
| 25 |
_loyaltyService = loyaltyService;
|
|
@@ -40,7 +41,7 @@ namespace Backend.Features.Subscriptions
|
|
| 40 |
}).ToListAsync();
|
| 41 |
}
|
| 42 |
|
| 43 |
-
public async Task<SubscriptionDto?> GetUserSubscriptionAsync(
|
| 44 |
{
|
| 45 |
var subscription = await _context.UserSubscriptions
|
| 46 |
.Include(s => s.Membership)
|
|
@@ -53,7 +54,7 @@ namespace Backend.Features.Subscriptions
|
|
| 53 |
return MapToDto(subscription);
|
| 54 |
}
|
| 55 |
|
| 56 |
-
public async Task<IEnumerable<SubscriptionDto>> GetUserAllSubscriptionsAsync(
|
| 57 |
{
|
| 58 |
var subscriptions = await _context.UserSubscriptions
|
| 59 |
.Include(s => s.Membership)
|
|
@@ -65,7 +66,7 @@ namespace Backend.Features.Subscriptions
|
|
| 65 |
return subscriptions.Select(MapToDto);
|
| 66 |
}
|
| 67 |
|
| 68 |
-
public async Task<bool> HandleLoyaltyRedemptionAsync(
|
| 69 |
{
|
| 70 |
try
|
| 71 |
{
|
|
@@ -112,7 +113,7 @@ namespace Backend.Features.Subscriptions
|
|
| 112 |
}
|
| 113 |
}
|
| 114 |
|
| 115 |
-
public async Task<SubscriptionDto> SubscribeUserAsync(
|
| 116 |
{
|
| 117 |
var membership = await _context.Memberships.FindAsync(membershipId);
|
| 118 |
if (membership == null) throw new Exception("Membership plan not found.");
|
|
|
|
| 1 |
+
using DbConnect.Data;
|
| 2 |
+
using DbConnect.Entities;
|
| 3 |
using Microsoft.EntityFrameworkCore;
|
| 4 |
using Backend.Features.Loyalty;
|
| 5 |
|
|
|
|
| 8 |
public interface ISubscriptionService
|
| 9 |
{
|
| 10 |
Task<IEnumerable<MembershipDto>> GetMembershipsAsync();
|
| 11 |
+
Task<SubscriptionDto?> GetUserSubscriptionAsync(Guid userId);
|
| 12 |
+
Task<IEnumerable<SubscriptionDto>> GetUserAllSubscriptionsAsync(Guid userId);
|
| 13 |
+
Task<bool> HandleLoyaltyRedemptionAsync(Guid userId, string rewardId, string rewardName, string redemptionId);
|
| 14 |
+
Task<SubscriptionDto> SubscribeUserAsync(Guid userId, int membershipId);
|
| 15 |
Task<IEnumerable<SubscriptionDto>> GetAllSubscriptionsAsync();
|
| 16 |
}
|
| 17 |
|
| 18 |
public class SubscriptionService : ISubscriptionService
|
| 19 |
{
|
| 20 |
+
private readonly AppDbContext _context;
|
| 21 |
private readonly ILoyaltyService _loyaltyService;
|
| 22 |
|
| 23 |
+
public SubscriptionService(AppDbContext context, ILoyaltyService loyaltyService)
|
| 24 |
{
|
| 25 |
_context = context;
|
| 26 |
_loyaltyService = loyaltyService;
|
|
|
|
| 41 |
}).ToListAsync();
|
| 42 |
}
|
| 43 |
|
| 44 |
+
public async Task<SubscriptionDto?> GetUserSubscriptionAsync(Guid userId)
|
| 45 |
{
|
| 46 |
var subscription = await _context.UserSubscriptions
|
| 47 |
.Include(s => s.Membership)
|
|
|
|
| 54 |
return MapToDto(subscription);
|
| 55 |
}
|
| 56 |
|
| 57 |
+
public async Task<IEnumerable<SubscriptionDto>> GetUserAllSubscriptionsAsync(Guid userId)
|
| 58 |
{
|
| 59 |
var subscriptions = await _context.UserSubscriptions
|
| 60 |
.Include(s => s.Membership)
|
|
|
|
| 66 |
return subscriptions.Select(MapToDto);
|
| 67 |
}
|
| 68 |
|
| 69 |
+
public async Task<bool> HandleLoyaltyRedemptionAsync(Guid userId, string rewardId, string rewardName, string redemptionId)
|
| 70 |
{
|
| 71 |
try
|
| 72 |
{
|
|
|
|
| 113 |
}
|
| 114 |
}
|
| 115 |
|
| 116 |
+
public async Task<SubscriptionDto> SubscribeUserAsync(Guid userId, int membershipId)
|
| 117 |
{
|
| 118 |
var membership = await _context.Memberships.FindAsync(membershipId);
|
| 119 |
if (membership == null) throw new Exception("Membership plan not found.");
|
Backend/Features/Users/UserController.cs
CHANGED
|
@@ -24,7 +24,7 @@ namespace Backend.Features.Users
|
|
| 24 |
|
| 25 |
[HttpGet("{id}")]
|
| 26 |
[Authorize(Roles = "Librarian")]
|
| 27 |
-
public async Task<ActionResult<UserDto>> GetUser(
|
| 28 |
{
|
| 29 |
var user = await _userService.GetUserByIdAsync(id);
|
| 30 |
if (user == null) return NotFound();
|
|
@@ -48,7 +48,7 @@ namespace Backend.Features.Users
|
|
| 48 |
|
| 49 |
[HttpPut("{id}")]
|
| 50 |
[Authorize(Roles = "Librarian")]
|
| 51 |
-
public async Task<ActionResult<UserDto>> UpdateUser(
|
| 52 |
{
|
| 53 |
var updatedUser = await _userService.UpdateUserAsync(id, request);
|
| 54 |
if (updatedUser == null) return NotFound();
|
|
@@ -57,7 +57,7 @@ namespace Backend.Features.Users
|
|
| 57 |
|
| 58 |
[HttpPatch("{id}/role")]
|
| 59 |
[Authorize(Roles = "Librarian")]
|
| 60 |
-
public async Task<IActionResult> UpdateUserRole(
|
| 61 |
{
|
| 62 |
var success = await _userService.UpdateUserRoleAsync(id, request.Role);
|
| 63 |
if (!success) return NotFound();
|
|
@@ -66,7 +66,7 @@ namespace Backend.Features.Users
|
|
| 66 |
|
| 67 |
[HttpDelete("{id}")]
|
| 68 |
[Authorize(Roles = "Librarian")]
|
| 69 |
-
public async Task<IActionResult> DeleteUser(
|
| 70 |
{
|
| 71 |
var success = await _userService.DeleteUserAsync(id);
|
| 72 |
if (!success) return NotFound();
|
|
|
|
| 24 |
|
| 25 |
[HttpGet("{id}")]
|
| 26 |
[Authorize(Roles = "Librarian")]
|
| 27 |
+
public async Task<ActionResult<UserDto>> GetUser(Guid id)
|
| 28 |
{
|
| 29 |
var user = await _userService.GetUserByIdAsync(id);
|
| 30 |
if (user == null) return NotFound();
|
|
|
|
| 48 |
|
| 49 |
[HttpPut("{id}")]
|
| 50 |
[Authorize(Roles = "Librarian")]
|
| 51 |
+
public async Task<ActionResult<UserDto>> UpdateUser(Guid id, [FromBody] UserUpdateRequest request)
|
| 52 |
{
|
| 53 |
var updatedUser = await _userService.UpdateUserAsync(id, request);
|
| 54 |
if (updatedUser == null) return NotFound();
|
|
|
|
| 57 |
|
| 58 |
[HttpPatch("{id}/role")]
|
| 59 |
[Authorize(Roles = "Librarian")]
|
| 60 |
+
public async Task<IActionResult> UpdateUserRole(Guid id, [FromBody] UserRoleUpdateRequest request)
|
| 61 |
{
|
| 62 |
var success = await _userService.UpdateUserRoleAsync(id, request.Role);
|
| 63 |
if (!success) return NotFound();
|
|
|
|
| 66 |
|
| 67 |
[HttpDelete("{id}")]
|
| 68 |
[Authorize(Roles = "Librarian")]
|
| 69 |
+
public async Task<IActionResult> DeleteUser(Guid id)
|
| 70 |
{
|
| 71 |
var success = await _userService.DeleteUserAsync(id);
|
| 72 |
if (!success) return NotFound();
|
Backend/Features/Users/UserService.cs
CHANGED
|
@@ -1,4 +1,5 @@
|
|
| 1 |
-
using
|
|
|
|
| 2 |
using Microsoft.EntityFrameworkCore;
|
| 3 |
using Backend.Features.Subscriptions;
|
| 4 |
using Backend.Features.Loyalty;
|
|
@@ -12,20 +13,20 @@ namespace Backend.Features.Users
|
|
| 12 |
public interface IUserService
|
| 13 |
{
|
| 14 |
Task<IEnumerable<UserDto>> GetAllUsersAsync();
|
| 15 |
-
Task<UserDto?> GetUserByIdAsync(
|
| 16 |
Task<UserDto> CreateUserAsync(UserCreateRequest request);
|
| 17 |
-
Task<UserDto?> UpdateUserAsync(
|
| 18 |
-
Task<bool> UpdateUserRoleAsync(
|
| 19 |
-
Task<bool> DeleteUserAsync(
|
| 20 |
}
|
| 21 |
|
| 22 |
public class UserService : IUserService
|
| 23 |
{
|
| 24 |
-
private readonly
|
| 25 |
private readonly ISubscriptionService _subscriptionService;
|
| 26 |
private readonly ILoyaltyService _loyaltyService;
|
| 27 |
|
| 28 |
-
public UserService(
|
| 29 |
{
|
| 30 |
_context = context;
|
| 31 |
_subscriptionService = subscriptionService;
|
|
@@ -38,7 +39,7 @@ namespace Backend.Features.Users
|
|
| 38 |
return users.Select(MapToDto);
|
| 39 |
}
|
| 40 |
|
| 41 |
-
public async Task<UserDto?> GetUserByIdAsync(
|
| 42 |
{
|
| 43 |
var user = await _context.Users.FindAsync(id);
|
| 44 |
return user == null ? null : MapToDto(user);
|
|
@@ -89,7 +90,7 @@ namespace Backend.Features.Users
|
|
| 89 |
return MapToDto(user);
|
| 90 |
}
|
| 91 |
|
| 92 |
-
public async Task<UserDto?> UpdateUserAsync(
|
| 93 |
{
|
| 94 |
var user = await _context.Users.FindAsync(id);
|
| 95 |
if (user == null) return null;
|
|
@@ -112,7 +113,7 @@ namespace Backend.Features.Users
|
|
| 112 |
return MapToDto(user);
|
| 113 |
}
|
| 114 |
|
| 115 |
-
public async Task<bool> UpdateUserRoleAsync(
|
| 116 |
{
|
| 117 |
var user = await _context.Users.FindAsync(id);
|
| 118 |
if (user == null) return false;
|
|
@@ -124,7 +125,7 @@ namespace Backend.Features.Users
|
|
| 124 |
return true;
|
| 125 |
}
|
| 126 |
|
| 127 |
-
public async Task<bool> DeleteUserAsync(
|
| 128 |
{
|
| 129 |
var user = await _context.Users.FindAsync(id);
|
| 130 |
if (user == null) return false;
|
|
@@ -159,7 +160,7 @@ namespace Backend.Features.Users
|
|
| 159 |
|
| 160 |
public class UserDto
|
| 161 |
{
|
| 162 |
-
public
|
| 163 |
public string Name => FullName;
|
| 164 |
public string FullName { get; set; } = string.Empty;
|
| 165 |
public string Email { get; set; } = string.Empty;
|
|
|
|
| 1 |
+
using DbConnect.Data;
|
| 2 |
+
using DbConnect.Entities;
|
| 3 |
using Microsoft.EntityFrameworkCore;
|
| 4 |
using Backend.Features.Subscriptions;
|
| 5 |
using Backend.Features.Loyalty;
|
|
|
|
| 13 |
public interface IUserService
|
| 14 |
{
|
| 15 |
Task<IEnumerable<UserDto>> GetAllUsersAsync();
|
| 16 |
+
Task<UserDto?> GetUserByIdAsync(Guid id);
|
| 17 |
Task<UserDto> CreateUserAsync(UserCreateRequest request);
|
| 18 |
+
Task<UserDto?> UpdateUserAsync(Guid id, UserUpdateRequest request);
|
| 19 |
+
Task<bool> UpdateUserRoleAsync(Guid id, string role);
|
| 20 |
+
Task<bool> DeleteUserAsync(Guid id);
|
| 21 |
}
|
| 22 |
|
| 23 |
public class UserService : IUserService
|
| 24 |
{
|
| 25 |
+
private readonly AppDbContext _context;
|
| 26 |
private readonly ISubscriptionService _subscriptionService;
|
| 27 |
private readonly ILoyaltyService _loyaltyService;
|
| 28 |
|
| 29 |
+
public UserService(AppDbContext context, ISubscriptionService subscriptionService, ILoyaltyService loyaltyService)
|
| 30 |
{
|
| 31 |
_context = context;
|
| 32 |
_subscriptionService = subscriptionService;
|
|
|
|
| 39 |
return users.Select(MapToDto);
|
| 40 |
}
|
| 41 |
|
| 42 |
+
public async Task<UserDto?> GetUserByIdAsync(Guid id)
|
| 43 |
{
|
| 44 |
var user = await _context.Users.FindAsync(id);
|
| 45 |
return user == null ? null : MapToDto(user);
|
|
|
|
| 90 |
return MapToDto(user);
|
| 91 |
}
|
| 92 |
|
| 93 |
+
public async Task<UserDto?> UpdateUserAsync(Guid id, UserUpdateRequest request)
|
| 94 |
{
|
| 95 |
var user = await _context.Users.FindAsync(id);
|
| 96 |
if (user == null) return null;
|
|
|
|
| 113 |
return MapToDto(user);
|
| 114 |
}
|
| 115 |
|
| 116 |
+
public async Task<bool> UpdateUserRoleAsync(Guid id, string role)
|
| 117 |
{
|
| 118 |
var user = await _context.Users.FindAsync(id);
|
| 119 |
if (user == null) return false;
|
|
|
|
| 125 |
return true;
|
| 126 |
}
|
| 127 |
|
| 128 |
+
public async Task<bool> DeleteUserAsync(Guid id)
|
| 129 |
{
|
| 130 |
var user = await _context.Users.FindAsync(id);
|
| 131 |
if (user == null) return false;
|
|
|
|
| 160 |
|
| 161 |
public class UserDto
|
| 162 |
{
|
| 163 |
+
public Guid Id { get; set; }
|
| 164 |
public string Name => FullName;
|
| 165 |
public string FullName { get; set; } = string.Empty;
|
| 166 |
public string Email { get; set; } = string.Empty;
|
Backend/Program.cs
CHANGED
|
@@ -1,5 +1,6 @@
|
|
| 1 |
using System.Text;
|
| 2 |
-
using
|
|
|
|
| 3 |
using Backend.Features.Auth;
|
| 4 |
using Backend.Features.Users;
|
| 5 |
using Backend.Features.Books;
|
|
@@ -46,7 +47,7 @@ builder.Services.AddSwaggerGen(c =>
|
|
| 46 |
});
|
| 47 |
});
|
| 48 |
|
| 49 |
-
builder.Services.AddDbContext<
|
| 50 |
options.UseSqlServer(builder.Configuration.GetConnectionString("MssqlConnection")));
|
| 51 |
|
| 52 |
// Register Services
|
|
|
|
| 1 |
using System.Text;
|
| 2 |
+
using DbConnect.Data;
|
| 3 |
+
using DbConnect.Entities;
|
| 4 |
using Backend.Features.Auth;
|
| 5 |
using Backend.Features.Users;
|
| 6 |
using Backend.Features.Books;
|
|
|
|
| 47 |
});
|
| 48 |
});
|
| 49 |
|
| 50 |
+
builder.Services.AddDbContext<AppDbContext>(options =>
|
| 51 |
options.UseSqlServer(builder.Configuration.GetConnectionString("MssqlConnection")));
|
| 52 |
|
| 53 |
// Register Services
|
Database/Models/Wishlist.cs
DELETED
|
@@ -1,17 +0,0 @@
|
|
| 1 |
-
using System;
|
| 2 |
-
using System.Collections.Generic;
|
| 3 |
-
|
| 4 |
-
namespace Database.Models;
|
| 5 |
-
|
| 6 |
-
public partial class Wishlist
|
| 7 |
-
{
|
| 8 |
-
public int Id { get; set; }
|
| 9 |
-
|
| 10 |
-
public int UserId { get; set; }
|
| 11 |
-
|
| 12 |
-
public int BookId { get; set; }
|
| 13 |
-
|
| 14 |
-
public virtual Book Book { get; set; } = null!;
|
| 15 |
-
|
| 16 |
-
public virtual User User { get; set; } = null!;
|
| 17 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Database/add_reward_id_to_memberships.sql
DELETED
|
@@ -1,14 +0,0 @@
|
|
| 1 |
-
USE LibraryManagement;
|
| 2 |
-
GO
|
| 3 |
-
|
| 4 |
-
-- Add RewardId column if it doesn't exist
|
| 5 |
-
IF NOT EXISTS (SELECT * FROM sys.columns WHERE object_id = OBJECT_ID('Memberships') AND name = 'RewardId')
|
| 6 |
-
BEGIN
|
| 7 |
-
ALTER TABLE Memberships ADD RewardId NVARCHAR(50) NULL;
|
| 8 |
-
END
|
| 9 |
-
GO
|
| 10 |
-
|
| 11 |
-
-- Populate RewardId for existing memberships
|
| 12 |
-
UPDATE Memberships SET RewardId = '39aff010-693e-450e-85e7-ae6c3f1a2078' WHERE Type = 'Basic Monthly';
|
| 13 |
-
UPDATE Memberships SET RewardId = '94bc0b20-1a87-4e10-a778-dd48552470d0' WHERE Type = 'Basic Yearly';
|
| 14 |
-
GO
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Database/db.sql
DELETED
|
@@ -1,112 +0,0 @@
|
|
| 1 |
-
-- Library Management System Database Schema (MSSQL)
|
| 2 |
-
CREATE DATABASE LibraryManagement;
|
| 3 |
-
GO
|
| 4 |
-
|
| 5 |
-
USE LibraryManagement;
|
| 6 |
-
GO
|
| 7 |
-
|
| 8 |
-
-- 1. Categories Table
|
| 9 |
-
CREATE TABLE Categories (
|
| 10 |
-
Id INT IDENTITY(1,1) PRIMARY KEY,
|
| 11 |
-
Name NVARCHAR(100) NOT NULL,
|
| 12 |
-
CONSTRAINT UQ_Categories_Name UNIQUE (Name)
|
| 13 |
-
);
|
| 14 |
-
GO
|
| 15 |
-
|
| 16 |
-
-- 2. Books Table
|
| 17 |
-
CREATE TABLE Books (
|
| 18 |
-
Id INT IDENTITY(1,1) PRIMARY KEY,
|
| 19 |
-
Title NVARCHAR(200) NOT NULL,
|
| 20 |
-
ISBN NVARCHAR(20) NOT NULL,
|
| 21 |
-
Author NVARCHAR(100) NOT NULL,
|
| 22 |
-
Status NVARCHAR(20) NOT NULL DEFAULT 'Available',
|
| 23 |
-
IsActive BIT NOT NULL DEFAULT 1,
|
| 24 |
-
CreatedAt DATETIME NOT NULL DEFAULT (GETDATE()),
|
| 25 |
-
Description NVARCHAR(MAX) NULL,
|
| 26 |
-
TotalCopies INT NOT NULL DEFAULT 1,
|
| 27 |
-
AvailableCopies INT NOT NULL DEFAULT 1,
|
| 28 |
-
UpdatedAt DATETIME NULL,
|
| 29 |
-
CONSTRAINT UQ_Books_ISBN UNIQUE (ISBN)
|
| 30 |
-
);
|
| 31 |
-
GO
|
| 32 |
-
|
| 33 |
-
-- 3. Users Table
|
| 34 |
-
CREATE TABLE Users (
|
| 35 |
-
Id INT IDENTITY(1,1) PRIMARY KEY,
|
| 36 |
-
FullName NVARCHAR(100) NOT NULL,
|
| 37 |
-
Email NVARCHAR(100) NOT NULL,
|
| 38 |
-
PasswordHash NVARCHAR(MAX) NOT NULL,
|
| 39 |
-
PhoneNumber NVARCHAR(20) NULL,
|
| 40 |
-
Role NVARCHAR(20) NOT NULL DEFAULT 'Member',
|
| 41 |
-
IsActive BIT NOT NULL DEFAULT 1,
|
| 42 |
-
CreatedAt DATETIME NOT NULL DEFAULT (GETDATE()),
|
| 43 |
-
UpdatedAt DATETIME NULL,
|
| 44 |
-
StudentId NVARCHAR(20) NULL,
|
| 45 |
-
BanStatus BIT NULL,
|
| 46 |
-
SuspensionEndDate DATETIME NULL,
|
| 47 |
-
Address NVARCHAR(255) NULL,
|
| 48 |
-
CONSTRAINT UQ_Users_Email UNIQUE (Email)
|
| 49 |
-
);
|
| 50 |
-
GO
|
| 51 |
-
|
| 52 |
-
-- 4. Memberships Table
|
| 53 |
-
CREATE TABLE Memberships (
|
| 54 |
-
Id INT IDENTITY(1,1) PRIMARY KEY,
|
| 55 |
-
Type NVARCHAR(50) NOT NULL,
|
| 56 |
-
MaxBooks INT NOT NULL,
|
| 57 |
-
BorrowingDays INT NOT NULL,
|
| 58 |
-
Price DECIMAL(10, 2) NOT NULL,
|
| 59 |
-
DurationMonths INT NOT NULL,
|
| 60 |
-
LoyaltyRewardId NVARCHAR(50) NULL,
|
| 61 |
-
CONSTRAINT IX_Memberships_Type UNIQUE (Type)
|
| 62 |
-
);
|
| 63 |
-
GO
|
| 64 |
-
|
| 65 |
-
-- 5. BookCategories (Many-to-Many Join Table)
|
| 66 |
-
CREATE TABLE BookCategories (
|
| 67 |
-
BookId INT NOT NULL,
|
| 68 |
-
CategoryId INT NOT NULL,
|
| 69 |
-
CONSTRAINT PK_BookCategories PRIMARY KEY (BookId, CategoryId),
|
| 70 |
-
CONSTRAINT FK_BookCategories_Books FOREIGN KEY (BookId) REFERENCES Books(Id) ON DELETE CASCADE,
|
| 71 |
-
CONSTRAINT FK_BookCategories_Categories FOREIGN KEY (CategoryId) REFERENCES Categories(Id) ON DELETE CASCADE
|
| 72 |
-
);
|
| 73 |
-
GO
|
| 74 |
-
|
| 75 |
-
-- 6. Borrowings Table
|
| 76 |
-
CREATE TABLE Borrowings (
|
| 77 |
-
Id INT IDENTITY(1,1) PRIMARY KEY,
|
| 78 |
-
UserId INT NOT NULL,
|
| 79 |
-
BookId INT NOT NULL,
|
| 80 |
-
BorrowDate DATETIME NOT NULL DEFAULT (GETDATE()),
|
| 81 |
-
DueDate DATETIME NOT NULL,
|
| 82 |
-
ReturnDate DATETIME NULL,
|
| 83 |
-
Status NVARCHAR(20) NOT NULL DEFAULT 'Active',
|
| 84 |
-
FineAmount DECIMAL(10, 2) NOT NULL DEFAULT 0.00,
|
| 85 |
-
IsFinePaid BIT NOT NULL DEFAULT 0,
|
| 86 |
-
CONSTRAINT FK_Borrowings_Users FOREIGN KEY (UserId) REFERENCES Users(Id),
|
| 87 |
-
CONSTRAINT FK_Borrowings_Books FOREIGN KEY (BookId) REFERENCES Books(Id)
|
| 88 |
-
);
|
| 89 |
-
GO
|
| 90 |
-
|
| 91 |
-
-- 7. UserSubscriptions Table
|
| 92 |
-
CREATE TABLE UserSubscriptions (
|
| 93 |
-
Id INT IDENTITY(1,1) PRIMARY KEY,
|
| 94 |
-
UserId INT NOT NULL,
|
| 95 |
-
MembershipId INT NOT NULL,
|
| 96 |
-
StartDate DATETIME NOT NULL,
|
| 97 |
-
ExpiryDate DATETIME NOT NULL,
|
| 98 |
-
IsActive BIT NOT NULL DEFAULT 1,
|
| 99 |
-
CONSTRAINT FK_UserSubscriptions_Users FOREIGN KEY (UserId) REFERENCES Users(Id),
|
| 100 |
-
CONSTRAINT FK_UserSubscriptions_Memberships FOREIGN KEY (MembershipId) REFERENCES Memberships(Id)
|
| 101 |
-
);
|
| 102 |
-
GO
|
| 103 |
-
|
| 104 |
-
-- 8. Wishlists Table
|
| 105 |
-
CREATE TABLE Wishlists (
|
| 106 |
-
Id INT IDENTITY(1,1) PRIMARY KEY,
|
| 107 |
-
UserId INT NOT NULL,
|
| 108 |
-
BookId INT NOT NULL,
|
| 109 |
-
CONSTRAINT FK_Wishlists_Users FOREIGN KEY (UserId) REFERENCES Users(Id),
|
| 110 |
-
CONSTRAINT FK_Wishlists_Books FOREIGN KEY (BookId) REFERENCES Books(Id)
|
| 111 |
-
);
|
| 112 |
-
GO
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Database/seed_data.sql
DELETED
|
@@ -1,86 +0,0 @@
|
|
| 1 |
-
-- Seed Data for Library Management System
|
| 2 |
-
USE LibraryManagement;
|
| 3 |
-
GO
|
| 4 |
-
|
| 5 |
-
-- 1. Insert Categories
|
| 6 |
-
SET IDENTITY_INSERT Categories ON;
|
| 7 |
-
INSERT INTO Categories (Id, Name) VALUES
|
| 8 |
-
(1, 'Fiction'),
|
| 9 |
-
(2, 'Science'),
|
| 10 |
-
(3, 'History'),
|
| 11 |
-
(4, 'Biography'),
|
| 12 |
-
(5, 'Technology'),
|
| 13 |
-
(6, 'Philosophy'),
|
| 14 |
-
(7, 'Self-Help'),
|
| 15 |
-
(8, 'Fantasy'),
|
| 16 |
-
(9, 'Mystery'),
|
| 17 |
-
(10, 'Business');
|
| 18 |
-
SET IDENTITY_INSERT Categories OFF;
|
| 19 |
-
GO
|
| 20 |
-
|
| 21 |
-
-- 2. Insert Memberships
|
| 22 |
-
SET IDENTITY_INSERT Memberships ON;
|
| 23 |
-
INSERT INTO Memberships (Id, Type, MaxBooks, BorrowingDays, Price, DurationMonths) VALUES
|
| 24 |
-
(1, 'Basic', 2, 7, 10.00, 1),
|
| 25 |
-
(2, 'Standard', 5, 14, 25.00, 3),
|
| 26 |
-
(3, 'Premium', 10, 30, 80.00, 12),
|
| 27 |
-
(4, 'Student', 3, 15, 15.00, 6);
|
| 28 |
-
SET IDENTITY_INSERT Memberships OFF;
|
| 29 |
-
GO
|
| 30 |
-
|
| 31 |
-
-- 3. Insert Users (Password is 'Password123' hashed typically, but using placeholder for SQL)
|
| 32 |
-
SET IDENTITY_INSERT Users ON;
|
| 33 |
-
INSERT INTO Users (Id, FullName, Email, PasswordHash, PhoneNumber, Role, IsActive, CreatedAt, Address) VALUES
|
| 34 |
-
(1, 'Admin User', 'admin@library.com', 'AQAAAAEAACcQAAAAE...', '09123456789', 'Admin', 1, GETDATE(), '123 Main St, Central City'),
|
| 35 |
-
(2, 'John Doe', 'john.doe@gmail.com', 'AQAAAAEAACcQAAAAE...', '09234567890', 'Member', 1, GETDATE(), '456 Oak Ave, North Side'),
|
| 36 |
-
(3, 'Jane Smith', 'jane.smith@yahoo.com', 'AQAAAAEAACcQAAAAE...', '09345678901', 'Member', 1, GETDATE(), '789 Pine Rd, South Village'),
|
| 37 |
-
(4, 'David Wilson', 'david.w@university.edu', 'AQAAAAEAACcQAAAAE...', '09456789012', 'Member', 1, GETDATE(), '101 University Dr, Campus'),
|
| 38 |
-
(5, 'Sarah Miller', 'sarah.m@gmail.com', 'AQAAAAEAACcQAAAAE...', '09567890123', 'Member', 1, GETDATE(), '202 Lake View, West Coast');
|
| 39 |
-
SET IDENTITY_INSERT Users OFF;
|
| 40 |
-
GO
|
| 41 |
-
|
| 42 |
-
-- 4. Insert Books
|
| 43 |
-
SET IDENTITY_INSERT Books ON;
|
| 44 |
-
INSERT INTO Books (Id, Title, ISBN, Author, Status, IsActive, CreatedAt, Description, TotalCopies, AvailableCopies) VALUES
|
| 45 |
-
(1, 'The Great Gatsby', '9780743273565', 'F. Scott Fitzgerald', 'Available', 1, GETDATE(), 'A classic novel of the Jazz Age.', 5, 5),
|
| 46 |
-
(2, 'A Brief History of Time', '9780553380163', 'Stephen Hawking', 'Available', 1, GETDATE(), 'Exploring the origin and fate of the universe.', 3, 3),
|
| 47 |
-
(3, 'Steve Jobs', '9781451648539', 'Walter Isaacson', 'Available', 1, GETDATE(), 'The exclusive biography of Steve Jobs.', 2, 2),
|
| 48 |
-
(4, 'The Pragmatic Programmer', '9780135957059', 'Andrew Hunt', 'Available', 1, GETDATE(), 'Your journey to mastery in software development.', 4, 4),
|
| 49 |
-
(5, 'Sapiens', '9780062316097', 'Yuval Noah Harari', 'Available', 1, GETDATE(), 'A brief history of humankind.', 6, 6),
|
| 50 |
-
(6, 'The Hobbit', '9780547928227', 'J.R.R. Tolkien', 'Available', 1, GETDATE(), 'A prelude to The Lord of the Rings.', 8, 8),
|
| 51 |
-
(7, 'Atomic Habits', '9780735211292', 'James Clear', 'Available', 1, GETDATE(), 'An easy & proven way to build good habits.', 10, 10),
|
| 52 |
-
(8, 'The Da Vinci Code', '9780307474278', 'Dan Brown', 'Available', 1, GETDATE(), 'A murder in the Louvre leads to a complex mystery.', 5, 5),
|
| 53 |
-
(9, 'Lean In', '9780385349949', 'Sheryl Sandberg', 'Available', 1, GETDATE(), 'Women, work, and the will to lead.', 3, 3),
|
| 54 |
-
(10, 'Clean Code', '9780132350884', 'Robert C. Martin', 'Available', 1, GETDATE(), 'A handbook of agile software craftsmanship.', 4, 4);
|
| 55 |
-
SET IDENTITY_INSERT Books OFF;
|
| 56 |
-
GO
|
| 57 |
-
|
| 58 |
-
-- 5. Book-Category Mapping
|
| 59 |
-
INSERT INTO BookCategories (BookId, CategoryId) VALUES
|
| 60 |
-
(1, 1), -- Great Gatsby - Fiction
|
| 61 |
-
(2, 2), -- Brief History - Science
|
| 62 |
-
(3, 4), -- Steve Jobs - Biography
|
| 63 |
-
(4, 5), -- Pragmatic Programmer - Technology
|
| 64 |
-
(5, 3), -- Sapiens - History
|
| 65 |
-
(6, 8), -- Hobbit - Fantasy
|
| 66 |
-
(7, 7), -- Atomic Habits - Self-Help
|
| 67 |
-
(8, 9), -- Da Vinci Code - Mystery
|
| 68 |
-
(9, 10), -- Lean In - Business
|
| 69 |
-
(10, 5); -- Clean Code - Technology
|
| 70 |
-
GO
|
| 71 |
-
|
| 72 |
-
-- 6. User Subscriptions
|
| 73 |
-
INSERT INTO UserSubscriptions (UserId, MembershipId, StartDate, ExpiryDate, IsActive) VALUES
|
| 74 |
-
(2, 2, '2026-01-01', '2026-04-01', 1),
|
| 75 |
-
(3, 3, '2026-01-01', '2027-01-01', 1),
|
| 76 |
-
(4, 4, '2026-02-15', '2026-08-15', 1),
|
| 77 |
-
(5, 1, '2026-04-01', '2026-05-01', 1);
|
| 78 |
-
GO
|
| 79 |
-
|
| 80 |
-
-- 7. Some Borrowing History
|
| 81 |
-
INSERT INTO Borrowings (UserId, BookId, BorrowDate, DueDate, ReturnDate, Status) VALUES
|
| 82 |
-
(2, 1, '2026-04-10', '2026-04-24', '2026-04-15', 'Returned'),
|
| 83 |
-
(2, 4, '2026-04-16', '2026-04-30', NULL, 'Active'),
|
| 84 |
-
(3, 7, '2026-04-01', '2026-05-01', NULL, 'Active'),
|
| 85 |
-
(4, 10, '2026-04-18', '2026-05-03', NULL, 'Active');
|
| 86 |
-
GO
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
DbConnect/Class1.cs
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
namespace DbConnect
|
| 2 |
+
{
|
| 3 |
+
public class Class1
|
| 4 |
+
{
|
| 5 |
+
|
| 6 |
+
}
|
| 7 |
+
}
|
Database/Models/LibraryManagementContext.cs → DbConnect/Data/AppDbContext.cs
RENAMED
|
@@ -1,16 +1,17 @@
|
|
| 1 |
-
using System;
|
| 2 |
using System.Collections.Generic;
|
|
|
|
| 3 |
using Microsoft.EntityFrameworkCore;
|
| 4 |
|
| 5 |
-
namespace
|
| 6 |
|
| 7 |
-
public partial class
|
| 8 |
{
|
| 9 |
-
public
|
| 10 |
{
|
| 11 |
}
|
| 12 |
|
| 13 |
-
public
|
| 14 |
: base(options)
|
| 15 |
{
|
| 16 |
}
|
|
@@ -27,7 +28,9 @@ public partial class LibraryManagementContext : DbContext
|
|
| 27 |
|
| 28 |
public virtual DbSet<UserSubscription> UserSubscriptions { get; set; }
|
| 29 |
|
| 30 |
-
|
|
|
|
|
|
|
| 31 |
|
| 32 |
protected override void OnModelCreating(ModelBuilder modelBuilder)
|
| 33 |
{
|
|
@@ -38,6 +41,7 @@ public partial class LibraryManagementContext : DbContext
|
|
| 38 |
entity.HasIndex(e => e.Isbn, "UQ__Books__447D36EA79CF66CE").IsUnique();
|
| 39 |
|
| 40 |
entity.Property(e => e.Author).HasMaxLength(100);
|
|
|
|
| 41 |
entity.Property(e => e.CreatedAt)
|
| 42 |
.HasDefaultValueSql("(getdate())")
|
| 43 |
.HasColumnType("datetime");
|
|
@@ -50,7 +54,6 @@ public partial class LibraryManagementContext : DbContext
|
|
| 50 |
.HasDefaultValue("Available");
|
| 51 |
entity.Property(e => e.Title).HasMaxLength(200);
|
| 52 |
entity.Property(e => e.TotalCopies).HasDefaultValue(1);
|
| 53 |
-
entity.Property(e => e.AvailableCopies).HasDefaultValue(1);
|
| 54 |
entity.Property(e => e.UpdatedAt).HasColumnType("datetime");
|
| 55 |
|
| 56 |
entity.HasMany(d => d.Categories).WithMany(p => p.Books)
|
|
@@ -71,8 +74,7 @@ public partial class LibraryManagementContext : DbContext
|
|
| 71 |
|
| 72 |
modelBuilder.Entity<Borrowing>(entity =>
|
| 73 |
{
|
| 74 |
-
entity.
|
| 75 |
-
|
| 76 |
entity.Property(e => e.BorrowDate)
|
| 77 |
.HasDefaultValueSql("(getdate())")
|
| 78 |
.HasColumnType("datetime");
|
|
@@ -110,15 +112,15 @@ public partial class LibraryManagementContext : DbContext
|
|
| 110 |
entity.HasIndex(e => e.Type, "IX_Memberships_Type").IsUnique();
|
| 111 |
|
| 112 |
entity.Property(e => e.Price).HasColumnType("decimal(10, 2)");
|
|
|
|
| 113 |
entity.Property(e => e.Type).HasMaxLength(50);
|
| 114 |
});
|
| 115 |
|
| 116 |
modelBuilder.Entity<User>(entity =>
|
| 117 |
{
|
| 118 |
-
entity.
|
| 119 |
-
|
| 120 |
-
entity.HasIndex(e => e.Email, "UQ__Users__A9D10534F91FFF73").IsUnique();
|
| 121 |
|
|
|
|
| 122 |
entity.Property(e => e.Address).HasMaxLength(255);
|
| 123 |
entity.Property(e => e.CreatedAt)
|
| 124 |
.HasDefaultValueSql("(getdate())")
|
|
@@ -129,7 +131,7 @@ public partial class LibraryManagementContext : DbContext
|
|
| 129 |
entity.Property(e => e.PhoneNumber).HasMaxLength(20);
|
| 130 |
entity.Property(e => e.Role)
|
| 131 |
.HasMaxLength(20)
|
| 132 |
-
.HasDefaultValue("
|
| 133 |
entity.Property(e => e.StudentId).HasMaxLength(20);
|
| 134 |
entity.Property(e => e.SuspensionEndDate).HasColumnType("datetime");
|
| 135 |
entity.Property(e => e.UpdatedAt).HasColumnType("datetime");
|
|
@@ -137,11 +139,14 @@ public partial class LibraryManagementContext : DbContext
|
|
| 137 |
|
| 138 |
modelBuilder.Entity<UserSubscription>(entity =>
|
| 139 |
{
|
| 140 |
-
entity.
|
| 141 |
-
|
| 142 |
entity.Property(e => e.ExpiryDate).HasColumnType("datetime");
|
|
|
|
| 143 |
entity.Property(e => e.IsActive).HasDefaultValue(true);
|
| 144 |
entity.Property(e => e.StartDate).HasColumnType("datetime");
|
|
|
|
|
|
|
|
|
|
| 145 |
|
| 146 |
entity.HasOne(d => d.Membership).WithMany(p => p.UserSubscriptions)
|
| 147 |
.HasForeignKey(d => d.MembershipId)
|
|
@@ -154,19 +159,6 @@ public partial class LibraryManagementContext : DbContext
|
|
| 154 |
.HasConstraintName("FK_UserSubscriptions_Users");
|
| 155 |
});
|
| 156 |
|
| 157 |
-
modelBuilder.Entity<Wishlist>(entity =>
|
| 158 |
-
{
|
| 159 |
-
entity.HasKey(e => e.Id).HasName("PK__Wishlist__3214EC07F63D8F81");
|
| 160 |
-
|
| 161 |
-
entity.HasOne(d => d.Book).WithMany(p => p.Wishlists)
|
| 162 |
-
.HasForeignKey(d => d.BookId)
|
| 163 |
-
.HasConstraintName("FK_Wishlists_Books");
|
| 164 |
-
|
| 165 |
-
entity.HasOne(d => d.User).WithMany(p => p.Wishlists)
|
| 166 |
-
.HasForeignKey(d => d.UserId)
|
| 167 |
-
.HasConstraintName("FK_Wishlists_Users");
|
| 168 |
-
});
|
| 169 |
-
|
| 170 |
OnModelCreatingPartial(modelBuilder);
|
| 171 |
}
|
| 172 |
|
|
|
|
| 1 |
+
using System;
|
| 2 |
using System.Collections.Generic;
|
| 3 |
+
using DbConnect.Entities;
|
| 4 |
using Microsoft.EntityFrameworkCore;
|
| 5 |
|
| 6 |
+
namespace DbConnect.Data;
|
| 7 |
|
| 8 |
+
public partial class AppDbContext : DbContext
|
| 9 |
{
|
| 10 |
+
public AppDbContext()
|
| 11 |
{
|
| 12 |
}
|
| 13 |
|
| 14 |
+
public AppDbContext(DbContextOptions<AppDbContext> options)
|
| 15 |
: base(options)
|
| 16 |
{
|
| 17 |
}
|
|
|
|
| 28 |
|
| 29 |
public virtual DbSet<UserSubscription> UserSubscriptions { get; set; }
|
| 30 |
|
| 31 |
+
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
|
| 32 |
+
#warning To protect potentially sensitive information in your connection string, you should move it out of source code. You can avoid scaffolding the connection string by using the Name= syntax to read it from configuration - see https://go.microsoft.com/fwlink/?linkid=2131148. For more guidance on storing connection strings, see https://go.microsoft.com/fwlink/?LinkId=723263.
|
| 33 |
+
=> optionsBuilder.UseSqlServer("Server=.;Database=LibraryManagement;User Id=sa;Password=sasa@123;TrustServerCertificate=True;");
|
| 34 |
|
| 35 |
protected override void OnModelCreating(ModelBuilder modelBuilder)
|
| 36 |
{
|
|
|
|
| 41 |
entity.HasIndex(e => e.Isbn, "UQ__Books__447D36EA79CF66CE").IsUnique();
|
| 42 |
|
| 43 |
entity.Property(e => e.Author).HasMaxLength(100);
|
| 44 |
+
entity.Property(e => e.AvailableCopies).HasDefaultValue(1);
|
| 45 |
entity.Property(e => e.CreatedAt)
|
| 46 |
.HasDefaultValueSql("(getdate())")
|
| 47 |
.HasColumnType("datetime");
|
|
|
|
| 54 |
.HasDefaultValue("Available");
|
| 55 |
entity.Property(e => e.Title).HasMaxLength(200);
|
| 56 |
entity.Property(e => e.TotalCopies).HasDefaultValue(1);
|
|
|
|
| 57 |
entity.Property(e => e.UpdatedAt).HasColumnType("datetime");
|
| 58 |
|
| 59 |
entity.HasMany(d => d.Categories).WithMany(p => p.Books)
|
|
|
|
| 74 |
|
| 75 |
modelBuilder.Entity<Borrowing>(entity =>
|
| 76 |
{
|
| 77 |
+
entity.Property(e => e.Id).HasDefaultValueSql("(newid())");
|
|
|
|
| 78 |
entity.Property(e => e.BorrowDate)
|
| 79 |
.HasDefaultValueSql("(getdate())")
|
| 80 |
.HasColumnType("datetime");
|
|
|
|
| 112 |
entity.HasIndex(e => e.Type, "IX_Memberships_Type").IsUnique();
|
| 113 |
|
| 114 |
entity.Property(e => e.Price).HasColumnType("decimal(10, 2)");
|
| 115 |
+
entity.Property(e => e.RewardId).HasMaxLength(100);
|
| 116 |
entity.Property(e => e.Type).HasMaxLength(50);
|
| 117 |
});
|
| 118 |
|
| 119 |
modelBuilder.Entity<User>(entity =>
|
| 120 |
{
|
| 121 |
+
entity.HasIndex(e => e.Email, "UQ_Users_Email").IsUnique();
|
|
|
|
|
|
|
| 122 |
|
| 123 |
+
entity.Property(e => e.Id).HasDefaultValueSql("(newid())");
|
| 124 |
entity.Property(e => e.Address).HasMaxLength(255);
|
| 125 |
entity.Property(e => e.CreatedAt)
|
| 126 |
.HasDefaultValueSql("(getdate())")
|
|
|
|
| 131 |
entity.Property(e => e.PhoneNumber).HasMaxLength(20);
|
| 132 |
entity.Property(e => e.Role)
|
| 133 |
.HasMaxLength(20)
|
| 134 |
+
.HasDefaultValue("User");
|
| 135 |
entity.Property(e => e.StudentId).HasMaxLength(20);
|
| 136 |
entity.Property(e => e.SuspensionEndDate).HasColumnType("datetime");
|
| 137 |
entity.Property(e => e.UpdatedAt).HasColumnType("datetime");
|
|
|
|
| 139 |
|
| 140 |
modelBuilder.Entity<UserSubscription>(entity =>
|
| 141 |
{
|
| 142 |
+
entity.Property(e => e.Id).HasDefaultValueSql("(newid())");
|
|
|
|
| 143 |
entity.Property(e => e.ExpiryDate).HasColumnType("datetime");
|
| 144 |
+
entity.Property(e => e.ExternalRedemptionId).HasMaxLength(100);
|
| 145 |
entity.Property(e => e.IsActive).HasDefaultValue(true);
|
| 146 |
entity.Property(e => e.StartDate).HasColumnType("datetime");
|
| 147 |
+
entity.Property(e => e.Status)
|
| 148 |
+
.HasMaxLength(20)
|
| 149 |
+
.HasDefaultValue("Active");
|
| 150 |
|
| 151 |
entity.HasOne(d => d.Membership).WithMany(p => p.UserSubscriptions)
|
| 152 |
.HasForeignKey(d => d.MembershipId)
|
|
|
|
| 159 |
.HasConstraintName("FK_UserSubscriptions_Users");
|
| 160 |
});
|
| 161 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 162 |
OnModelCreatingPartial(modelBuilder);
|
| 163 |
}
|
| 164 |
|
Database/Database.csproj → DbConnect/DbConnect.csproj
RENAMED
|
File without changes
|
{Database/Models → DbConnect/Entities}/Book.cs
RENAMED
|
@@ -1,7 +1,7 @@
|
|
| 1 |
-
using System;
|
| 2 |
using System.Collections.Generic;
|
| 3 |
|
| 4 |
-
namespace
|
| 5 |
|
| 6 |
public partial class Book
|
| 7 |
{
|
|
@@ -20,16 +20,16 @@ public partial class Book
|
|
| 20 |
public DateTime CreatedAt { get; set; }
|
| 21 |
|
| 22 |
public string? Description { get; set; }
|
| 23 |
-
|
|
|
|
|
|
|
| 24 |
public int TotalCopies { get; set; }
|
| 25 |
-
|
| 26 |
public int AvailableCopies { get; set; }
|
| 27 |
-
|
| 28 |
public DateTime? UpdatedAt { get; set; }
|
| 29 |
|
| 30 |
public virtual ICollection<Borrowing> Borrowings { get; set; } = new List<Borrowing>();
|
| 31 |
|
| 32 |
-
public virtual ICollection<Wishlist> Wishlists { get; set; } = new List<Wishlist>();
|
| 33 |
-
|
| 34 |
public virtual ICollection<Category> Categories { get; set; } = new List<Category>();
|
| 35 |
}
|
|
|
|
| 1 |
+
using System;
|
| 2 |
using System.Collections.Generic;
|
| 3 |
|
| 4 |
+
namespace DbConnect.Entities;
|
| 5 |
|
| 6 |
public partial class Book
|
| 7 |
{
|
|
|
|
| 20 |
public DateTime CreatedAt { get; set; }
|
| 21 |
|
| 22 |
public string? Description { get; set; }
|
| 23 |
+
|
| 24 |
+
public string? CoverUrl { get; set; }
|
| 25 |
+
|
| 26 |
public int TotalCopies { get; set; }
|
| 27 |
+
|
| 28 |
public int AvailableCopies { get; set; }
|
| 29 |
+
|
| 30 |
public DateTime? UpdatedAt { get; set; }
|
| 31 |
|
| 32 |
public virtual ICollection<Borrowing> Borrowings { get; set; } = new List<Borrowing>();
|
| 33 |
|
|
|
|
|
|
|
| 34 |
public virtual ICollection<Category> Categories { get; set; } = new List<Category>();
|
| 35 |
}
|
{Database/Models → DbConnect/Entities}/Borrowing.cs
RENAMED
|
@@ -1,13 +1,13 @@
|
|
| 1 |
using System;
|
| 2 |
using System.Collections.Generic;
|
| 3 |
|
| 4 |
-
namespace
|
| 5 |
|
| 6 |
public partial class Borrowing
|
| 7 |
{
|
| 8 |
-
public
|
| 9 |
|
| 10 |
-
public
|
| 11 |
|
| 12 |
public int BookId { get; set; }
|
| 13 |
|
|
|
|
| 1 |
using System;
|
| 2 |
using System.Collections.Generic;
|
| 3 |
|
| 4 |
+
namespace DbConnect.Entities;
|
| 5 |
|
| 6 |
public partial class Borrowing
|
| 7 |
{
|
| 8 |
+
public Guid Id { get; set; }
|
| 9 |
|
| 10 |
+
public Guid UserId { get; set; }
|
| 11 |
|
| 12 |
public int BookId { get; set; }
|
| 13 |
|
{Database/Models → DbConnect/Entities}/Category.cs
RENAMED
|
@@ -1,7 +1,7 @@
|
|
| 1 |
using System;
|
| 2 |
using System.Collections.Generic;
|
| 3 |
|
| 4 |
-
namespace
|
| 5 |
|
| 6 |
public partial class Category
|
| 7 |
{
|
|
|
|
| 1 |
using System;
|
| 2 |
using System.Collections.Generic;
|
| 3 |
|
| 4 |
+
namespace DbConnect.Entities;
|
| 5 |
|
| 6 |
public partial class Category
|
| 7 |
{
|
{Database/Models → DbConnect/Entities}/Membership.cs
RENAMED
|
@@ -1,7 +1,7 @@
|
|
| 1 |
-
using System;
|
| 2 |
using System.Collections.Generic;
|
| 3 |
|
| 4 |
-
namespace
|
| 5 |
|
| 6 |
public partial class Membership
|
| 7 |
{
|
|
@@ -16,6 +16,7 @@ public partial class Membership
|
|
| 16 |
public decimal Price { get; set; }
|
| 17 |
|
| 18 |
public int DurationMonths { get; set; }
|
|
|
|
| 19 |
public string? RewardId { get; set; }
|
| 20 |
|
| 21 |
public virtual ICollection<UserSubscription> UserSubscriptions { get; set; } = new List<UserSubscription>();
|
|
|
|
| 1 |
+
using System;
|
| 2 |
using System.Collections.Generic;
|
| 3 |
|
| 4 |
+
namespace DbConnect.Entities;
|
| 5 |
|
| 6 |
public partial class Membership
|
| 7 |
{
|
|
|
|
| 16 |
public decimal Price { get; set; }
|
| 17 |
|
| 18 |
public int DurationMonths { get; set; }
|
| 19 |
+
|
| 20 |
public string? RewardId { get; set; }
|
| 21 |
|
| 22 |
public virtual ICollection<UserSubscription> UserSubscriptions { get; set; } = new List<UserSubscription>();
|
{Database/Models → DbConnect/Entities}/User.cs
RENAMED
|
@@ -1,11 +1,11 @@
|
|
| 1 |
using System;
|
| 2 |
using System.Collections.Generic;
|
| 3 |
|
| 4 |
-
namespace
|
| 5 |
|
| 6 |
public partial class User
|
| 7 |
{
|
| 8 |
-
public
|
| 9 |
|
| 10 |
public string FullName { get; set; } = null!;
|
| 11 |
|
|
@@ -34,6 +34,4 @@ public partial class User
|
|
| 34 |
public virtual ICollection<Borrowing> Borrowings { get; set; } = new List<Borrowing>();
|
| 35 |
|
| 36 |
public virtual ICollection<UserSubscription> UserSubscriptions { get; set; } = new List<UserSubscription>();
|
| 37 |
-
|
| 38 |
-
public virtual ICollection<Wishlist> Wishlists { get; set; } = new List<Wishlist>();
|
| 39 |
}
|
|
|
|
| 1 |
using System;
|
| 2 |
using System.Collections.Generic;
|
| 3 |
|
| 4 |
+
namespace DbConnect.Entities;
|
| 5 |
|
| 6 |
public partial class User
|
| 7 |
{
|
| 8 |
+
public Guid Id { get; set; }
|
| 9 |
|
| 10 |
public string FullName { get; set; } = null!;
|
| 11 |
|
|
|
|
| 34 |
public virtual ICollection<Borrowing> Borrowings { get; set; } = new List<Borrowing>();
|
| 35 |
|
| 36 |
public virtual ICollection<UserSubscription> UserSubscriptions { get; set; } = new List<UserSubscription>();
|
|
|
|
|
|
|
| 37 |
}
|
{Database/Models → DbConnect/Entities}/UserSubscription.cs
RENAMED
|
@@ -1,13 +1,13 @@
|
|
| 1 |
using System;
|
| 2 |
using System.Collections.Generic;
|
| 3 |
|
| 4 |
-
namespace
|
| 5 |
|
| 6 |
public partial class UserSubscription
|
| 7 |
{
|
| 8 |
-
public
|
| 9 |
|
| 10 |
-
public
|
| 11 |
|
| 12 |
public int MembershipId { get; set; }
|
| 13 |
|
|
@@ -17,6 +17,10 @@ public partial class UserSubscription
|
|
| 17 |
|
| 18 |
public bool IsActive { get; set; }
|
| 19 |
|
|
|
|
|
|
|
|
|
|
|
|
|
| 20 |
public virtual Membership Membership { get; set; } = null!;
|
| 21 |
|
| 22 |
public virtual User User { get; set; } = null!;
|
|
|
|
| 1 |
using System;
|
| 2 |
using System.Collections.Generic;
|
| 3 |
|
| 4 |
+
namespace DbConnect.Entities;
|
| 5 |
|
| 6 |
public partial class UserSubscription
|
| 7 |
{
|
| 8 |
+
public Guid Id { get; set; }
|
| 9 |
|
| 10 |
+
public Guid UserId { get; set; }
|
| 11 |
|
| 12 |
public int MembershipId { get; set; }
|
| 13 |
|
|
|
|
| 17 |
|
| 18 |
public bool IsActive { get; set; }
|
| 19 |
|
| 20 |
+
public string Status { get; set; } = null!;
|
| 21 |
+
|
| 22 |
+
public string? ExternalRedemptionId { get; set; }
|
| 23 |
+
|
| 24 |
public virtual Membership Membership { get; set; } = null!;
|
| 25 |
|
| 26 |
public virtual User User { get; set; } = null!;
|
Frontend/Controllers/BorrowingsController.cs
CHANGED
|
@@ -22,7 +22,7 @@ namespace Frontend.Controllers
|
|
| 22 |
}
|
| 23 |
|
| 24 |
[HttpPost]
|
| 25 |
-
public async Task<IActionResult> RequestReturn(
|
| 26 |
{
|
| 27 |
var success = await _apiClient.RequestReturnAsync(id);
|
| 28 |
if (success)
|
|
@@ -76,7 +76,7 @@ namespace Frontend.Controllers
|
|
| 76 |
|
| 77 |
[HttpPost]
|
| 78 |
[Authorize(Roles = "Librarian")]
|
| 79 |
-
public async Task<IActionResult> Return(
|
| 80 |
{
|
| 81 |
var result = await _apiClient.ReturnBookAsync(id);
|
| 82 |
if (result != null)
|
|
|
|
| 22 |
}
|
| 23 |
|
| 24 |
[HttpPost]
|
| 25 |
+
public async Task<IActionResult> RequestReturn(Guid id)
|
| 26 |
{
|
| 27 |
var success = await _apiClient.RequestReturnAsync(id);
|
| 28 |
if (success)
|
|
|
|
| 76 |
|
| 77 |
[HttpPost]
|
| 78 |
[Authorize(Roles = "Librarian")]
|
| 79 |
+
public async Task<IActionResult> Return(Guid id, bool fromManage = false)
|
| 80 |
{
|
| 81 |
var result = await _apiClient.ReturnBookAsync(id);
|
| 82 |
if (result != null)
|
Frontend/Controllers/MembersController.cs
CHANGED
|
@@ -35,7 +35,7 @@ namespace Frontend.Controllers
|
|
| 35 |
return View(pagedResult);
|
| 36 |
}
|
| 37 |
|
| 38 |
-
public async Task<IActionResult> Details(
|
| 39 |
{
|
| 40 |
var user = await _apiClient.GetUserAsync(id);
|
| 41 |
if (user == null) return NotFound();
|
|
@@ -54,7 +54,7 @@ namespace Frontend.Controllers
|
|
| 54 |
}
|
| 55 |
|
| 56 |
[HttpPost]
|
| 57 |
-
public async Task<IActionResult> AssignSubscription(
|
| 58 |
{
|
| 59 |
var request = new AdminSubscribeRequest { UserId = id, MembershipId = membershipId };
|
| 60 |
var result = await _apiClient.AdminSubscribeAsync(request);
|
|
@@ -92,7 +92,7 @@ namespace Frontend.Controllers
|
|
| 92 |
}
|
| 93 |
|
| 94 |
[HttpGet]
|
| 95 |
-
public async Task<IActionResult> Edit(
|
| 96 |
{
|
| 97 |
var user = await _apiClient.GetUserAsync(id);
|
| 98 |
if (user == null) return NotFound();
|
|
@@ -107,7 +107,7 @@ namespace Frontend.Controllers
|
|
| 107 |
}
|
| 108 |
|
| 109 |
[HttpPost]
|
| 110 |
-
public async Task<IActionResult> Edit(
|
| 111 |
{
|
| 112 |
if (!ModelState.IsValid) return View(request);
|
| 113 |
|
|
@@ -123,7 +123,7 @@ namespace Frontend.Controllers
|
|
| 123 |
}
|
| 124 |
|
| 125 |
[HttpPost]
|
| 126 |
-
public async Task<IActionResult> Delete(
|
| 127 |
{
|
| 128 |
var success = await _apiClient.DeleteUserAsync(id);
|
| 129 |
if (success)
|
|
@@ -138,7 +138,7 @@ namespace Frontend.Controllers
|
|
| 138 |
}
|
| 139 |
|
| 140 |
[HttpPost]
|
| 141 |
-
public async Task<IActionResult> UpdateRole(
|
| 142 |
{
|
| 143 |
var success = await _apiClient.UpdateUserRoleAsync(id, role);
|
| 144 |
if (success)
|
|
|
|
| 35 |
return View(pagedResult);
|
| 36 |
}
|
| 37 |
|
| 38 |
+
public async Task<IActionResult> Details(Guid id)
|
| 39 |
{
|
| 40 |
var user = await _apiClient.GetUserAsync(id);
|
| 41 |
if (user == null) return NotFound();
|
|
|
|
| 54 |
}
|
| 55 |
|
| 56 |
[HttpPost]
|
| 57 |
+
public async Task<IActionResult> AssignSubscription(Guid id, int membershipId)
|
| 58 |
{
|
| 59 |
var request = new AdminSubscribeRequest { UserId = id, MembershipId = membershipId };
|
| 60 |
var result = await _apiClient.AdminSubscribeAsync(request);
|
|
|
|
| 92 |
}
|
| 93 |
|
| 94 |
[HttpGet]
|
| 95 |
+
public async Task<IActionResult> Edit(Guid id)
|
| 96 |
{
|
| 97 |
var user = await _apiClient.GetUserAsync(id);
|
| 98 |
if (user == null) return NotFound();
|
|
|
|
| 107 |
}
|
| 108 |
|
| 109 |
[HttpPost]
|
| 110 |
+
public async Task<IActionResult> Edit(Guid id, UserUpdateRequest request)
|
| 111 |
{
|
| 112 |
if (!ModelState.IsValid) return View(request);
|
| 113 |
|
|
|
|
| 123 |
}
|
| 124 |
|
| 125 |
[HttpPost]
|
| 126 |
+
public async Task<IActionResult> Delete(Guid id)
|
| 127 |
{
|
| 128 |
var success = await _apiClient.DeleteUserAsync(id);
|
| 129 |
if (success)
|
|
|
|
| 138 |
}
|
| 139 |
|
| 140 |
[HttpPost]
|
| 141 |
+
public async Task<IActionResult> UpdateRole(Guid id, string role)
|
| 142 |
{
|
| 143 |
var success = await _apiClient.UpdateUserRoleAsync(id, role);
|
| 144 |
if (success)
|
Frontend/Models/Dtos/LibraryDtos.cs
CHANGED
|
@@ -72,8 +72,8 @@ namespace Frontend.Models.Dtos
|
|
| 72 |
// Borrowing DTOs
|
| 73 |
public class BorrowingDto
|
| 74 |
{
|
| 75 |
-
public
|
| 76 |
-
public
|
| 77 |
public string UserEmail { get; set; } = string.Empty;
|
| 78 |
public int BookId { get; set; }
|
| 79 |
public string BookTitle { get; set; } = string.Empty;
|
|
@@ -116,8 +116,8 @@ namespace Frontend.Models.Dtos
|
|
| 116 |
|
| 117 |
public class SubscriptionDto
|
| 118 |
{
|
| 119 |
-
public
|
| 120 |
-
public
|
| 121 |
public int MembershipId { get; set; }
|
| 122 |
public string MembershipType { get; set; } = string.Empty;
|
| 123 |
public string UserName { get; set; } = string.Empty;
|
|
@@ -135,7 +135,7 @@ namespace Frontend.Models.Dtos
|
|
| 135 |
|
| 136 |
public class AdminSubscribeRequest
|
| 137 |
{
|
| 138 |
-
public
|
| 139 |
public int MembershipId { get; set; }
|
| 140 |
}
|
| 141 |
|
|
@@ -188,7 +188,7 @@ namespace Frontend.Models.Dtos
|
|
| 188 |
// User DTOs
|
| 189 |
public class UserDto
|
| 190 |
{
|
| 191 |
-
public
|
| 192 |
public string FullName { get; set; } = string.Empty;
|
| 193 |
public string Email { get; set; } = string.Empty;
|
| 194 |
public string? PhoneNumber { get; set; }
|
|
|
|
| 72 |
// Borrowing DTOs
|
| 73 |
public class BorrowingDto
|
| 74 |
{
|
| 75 |
+
public Guid Id { get; set; }
|
| 76 |
+
public Guid UserId { get; set; }
|
| 77 |
public string UserEmail { get; set; } = string.Empty;
|
| 78 |
public int BookId { get; set; }
|
| 79 |
public string BookTitle { get; set; } = string.Empty;
|
|
|
|
| 116 |
|
| 117 |
public class SubscriptionDto
|
| 118 |
{
|
| 119 |
+
public Guid Id { get; set; }
|
| 120 |
+
public Guid UserId { get; set; }
|
| 121 |
public int MembershipId { get; set; }
|
| 122 |
public string MembershipType { get; set; } = string.Empty;
|
| 123 |
public string UserName { get; set; } = string.Empty;
|
|
|
|
| 135 |
|
| 136 |
public class AdminSubscribeRequest
|
| 137 |
{
|
| 138 |
+
public Guid UserId { get; set; }
|
| 139 |
public int MembershipId { get; set; }
|
| 140 |
}
|
| 141 |
|
|
|
|
| 188 |
// User DTOs
|
| 189 |
public class UserDto
|
| 190 |
{
|
| 191 |
+
public Guid Id { get; set; }
|
| 192 |
public string FullName { get; set; } = string.Empty;
|
| 193 |
public string Email { get; set; } = string.Empty;
|
| 194 |
public string? PhoneNumber { get; set; }
|
Frontend/Services/LibraryApiClient.cs
CHANGED
|
@@ -91,7 +91,7 @@ namespace Frontend.Services
|
|
| 91 |
return response.IsSuccessStatusCode ? await response.Content.ReadFromJsonAsync<BorrowingDto>() : null;
|
| 92 |
}
|
| 93 |
|
| 94 |
-
public async Task<BorrowingDto?> ReturnBookAsync(
|
| 95 |
{
|
| 96 |
var response = await _httpClient.PostAsync($"api/borrowings/return/{id}", null);
|
| 97 |
return response.IsSuccessStatusCode ? await response.Content.ReadFromJsonAsync<BorrowingDto>() : null;
|
|
@@ -158,7 +158,7 @@ namespace Frontend.Services
|
|
| 158 |
return response.IsSuccessStatusCode ? await response.Content.ReadFromJsonAsync<SubscriptionDto>() : null;
|
| 159 |
}
|
| 160 |
|
| 161 |
-
public async Task<SubscriptionDto?> GetUserSubscriptionAsync(
|
| 162 |
{
|
| 163 |
try {
|
| 164 |
return await _httpClient.GetFromJsonAsync<SubscriptionDto>($"api/subscriptions/user/{userId}");
|
|
@@ -208,7 +208,7 @@ namespace Frontend.Services
|
|
| 208 |
} catch { return Enumerable.Empty<LoyaltyRedemptionDto>(); }
|
| 209 |
}
|
| 210 |
|
| 211 |
-
public async Task<bool> RequestReturnAsync(
|
| 212 |
{
|
| 213 |
var response = await _httpClient.PostAsync($"api/borrowings/return-request/{borrowingId}", null);
|
| 214 |
return response.IsSuccessStatusCode;
|
|
@@ -269,7 +269,7 @@ namespace Frontend.Services
|
|
| 269 |
return await _httpClient.GetFromJsonAsync<IEnumerable<UserDto>>("api/users") ?? Enumerable.Empty<UserDto>();
|
| 270 |
}
|
| 271 |
|
| 272 |
-
public async Task<UserDto?> GetUserAsync(
|
| 273 |
{
|
| 274 |
return await _httpClient.GetFromJsonAsync<UserDto>($"api/users/{id}");
|
| 275 |
}
|
|
@@ -280,19 +280,19 @@ namespace Frontend.Services
|
|
| 280 |
return response.IsSuccessStatusCode ? await response.Content.ReadFromJsonAsync<UserDto>() : null;
|
| 281 |
}
|
| 282 |
|
| 283 |
-
public async Task<UserDto?> UpdateUserAsync(
|
| 284 |
{
|
| 285 |
var response = await _httpClient.PutAsJsonAsync($"api/users/{id}", request);
|
| 286 |
return response.IsSuccessStatusCode ? await response.Content.ReadFromJsonAsync<UserDto>() : null;
|
| 287 |
}
|
| 288 |
|
| 289 |
-
public async Task<bool> UpdateUserRoleAsync(
|
| 290 |
{
|
| 291 |
var response = await _httpClient.PutAsJsonAsync($"api/users/role/{id}", new UserRoleUpdateRequest { Role = role });
|
| 292 |
return response.IsSuccessStatusCode;
|
| 293 |
}
|
| 294 |
|
| 295 |
-
public async Task<bool> DeleteUserAsync(
|
| 296 |
{
|
| 297 |
var response = await _httpClient.DeleteAsync($"api/users/{id}");
|
| 298 |
return response.IsSuccessStatusCode;
|
|
|
|
| 91 |
return response.IsSuccessStatusCode ? await response.Content.ReadFromJsonAsync<BorrowingDto>() : null;
|
| 92 |
}
|
| 93 |
|
| 94 |
+
public async Task<BorrowingDto?> ReturnBookAsync(Guid id)
|
| 95 |
{
|
| 96 |
var response = await _httpClient.PostAsync($"api/borrowings/return/{id}", null);
|
| 97 |
return response.IsSuccessStatusCode ? await response.Content.ReadFromJsonAsync<BorrowingDto>() : null;
|
|
|
|
| 158 |
return response.IsSuccessStatusCode ? await response.Content.ReadFromJsonAsync<SubscriptionDto>() : null;
|
| 159 |
}
|
| 160 |
|
| 161 |
+
public async Task<SubscriptionDto?> GetUserSubscriptionAsync(Guid userId)
|
| 162 |
{
|
| 163 |
try {
|
| 164 |
return await _httpClient.GetFromJsonAsync<SubscriptionDto>($"api/subscriptions/user/{userId}");
|
|
|
|
| 208 |
} catch { return Enumerable.Empty<LoyaltyRedemptionDto>(); }
|
| 209 |
}
|
| 210 |
|
| 211 |
+
public async Task<bool> RequestReturnAsync(Guid borrowingId)
|
| 212 |
{
|
| 213 |
var response = await _httpClient.PostAsync($"api/borrowings/return-request/{borrowingId}", null);
|
| 214 |
return response.IsSuccessStatusCode;
|
|
|
|
| 269 |
return await _httpClient.GetFromJsonAsync<IEnumerable<UserDto>>("api/users") ?? Enumerable.Empty<UserDto>();
|
| 270 |
}
|
| 271 |
|
| 272 |
+
public async Task<UserDto?> GetUserAsync(Guid id)
|
| 273 |
{
|
| 274 |
return await _httpClient.GetFromJsonAsync<UserDto>($"api/users/{id}");
|
| 275 |
}
|
|
|
|
| 280 |
return response.IsSuccessStatusCode ? await response.Content.ReadFromJsonAsync<UserDto>() : null;
|
| 281 |
}
|
| 282 |
|
| 283 |
+
public async Task<UserDto?> UpdateUserAsync(Guid id, UserUpdateRequest request)
|
| 284 |
{
|
| 285 |
var response = await _httpClient.PutAsJsonAsync($"api/users/{id}", request);
|
| 286 |
return response.IsSuccessStatusCode ? await response.Content.ReadFromJsonAsync<UserDto>() : null;
|
| 287 |
}
|
| 288 |
|
| 289 |
+
public async Task<bool> UpdateUserRoleAsync(Guid id, string role)
|
| 290 |
{
|
| 291 |
var response = await _httpClient.PutAsJsonAsync($"api/users/role/{id}", new UserRoleUpdateRequest { Role = role });
|
| 292 |
return response.IsSuccessStatusCode;
|
| 293 |
}
|
| 294 |
|
| 295 |
+
public async Task<bool> DeleteUserAsync(Guid id)
|
| 296 |
{
|
| 297 |
var response = await _httpClient.DeleteAsync($"api/users/{id}");
|
| 298 |
return response.IsSuccessStatusCode;
|
LibraryManagement.slnx
CHANGED
|
@@ -1,5 +1,5 @@
|
|
| 1 |
<Solution>
|
| 2 |
<Project Path="Backend/Backend.csproj" Id="82e311b1-ce76-4235-9d5f-0d06a942d038" />
|
| 3 |
-
<Project Path="
|
| 4 |
<Project Path="Frontend/Frontend.csproj" Id="824d7fed-4fd3-41c5-8c5e-acd458ccbcdb" />
|
| 5 |
</Solution>
|
|
|
|
| 1 |
<Solution>
|
| 2 |
<Project Path="Backend/Backend.csproj" Id="82e311b1-ce76-4235-9d5f-0d06a942d038" />
|
| 3 |
+
<Project Path="DbConnect/DbConnect.csproj" Id="9923b718-c896-438d-ba4b-a2065f91c8ab" />
|
| 4 |
<Project Path="Frontend/Frontend.csproj" Id="824d7fed-4fd3-41c5-8c5e-acd458ccbcdb" />
|
| 5 |
</Solution>
|