sannlynnhtun-coding commited on
Commit
97af519
·
1 Parent(s): 24fa936

chore: remove backend project files and configurations for Library Management System

Browse files
LibraryManagement.Backend/Features/Auth/AuthController.cs DELETED
@@ -1,59 +0,0 @@
1
- using Microsoft.AspNetCore.Authorization;
2
- using Microsoft.AspNetCore.Mvc;
3
- using System.Security.Claims;
4
-
5
- namespace LibraryManagement.Backend.Features.Auth
6
- {
7
- [ApiController]
8
- [Route("api/auth")]
9
- public class AuthController : ControllerBase
10
- {
11
- private readonly IAuthService _authService;
12
-
13
- public AuthController(IAuthService authService)
14
- {
15
- _authService = authService;
16
- }
17
-
18
- [HttpPost("register")]
19
- public async Task<ActionResult<AuthResponse>> Register([FromBody] RegisterRequest request)
20
- {
21
- try
22
- {
23
- var response = await _authService.Register(request);
24
- return Ok(response);
25
- }
26
- catch (Exception ex)
27
- {
28
- return BadRequest(new { message = ex.Message });
29
- }
30
- }
31
-
32
- [HttpPost("login")]
33
- public async Task<ActionResult<AuthResponse>> Login([FromBody] LoginRequest request)
34
- {
35
- try
36
- {
37
- var response = await _authService.Login(request);
38
- return Ok(response);
39
- }
40
- catch (Exception ex)
41
- {
42
- return Unauthorized(new { message = ex.Message });
43
- }
44
- }
45
-
46
- [HttpGet("me")]
47
- [Authorize]
48
- public IActionResult GetCurrentUser()
49
- {
50
- var claims = User.Claims.Select(c => new { c.Type, c.Value }).ToList();
51
- return Ok(new
52
- {
53
- IsAuthenticated = User.Identity?.IsAuthenticated,
54
- Name = User.Identity?.Name,
55
- Claims = claims
56
- });
57
- }
58
- }
59
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
LibraryManagement.Backend/Features/Auth/AuthModels.cs DELETED
@@ -1,26 +0,0 @@
1
- namespace LibraryManagement.Backend.Features.Auth
2
- {
3
- public class RegisterRequest
4
- {
5
- public string FullName { get; set; } = string.Empty;
6
- public string Email { get; set; } = string.Empty;
7
- public string Password { get; set; } = string.Empty;
8
- public string? PhoneNumber { get; set; }
9
- public string? Address { get; set; }
10
- public string? StudentId { get; set; }
11
- }
12
-
13
- public class LoginRequest
14
- {
15
- public string Email { get; set; } = string.Empty;
16
- public string Password { get; set; } = string.Empty;
17
- }
18
-
19
- public class AuthResponse
20
- {
21
- public string Token { get; set; } = string.Empty;
22
- public string FullName { get; set; } = string.Empty;
23
- public string Role { get; set; } = string.Empty;
24
- public DateTime Expiry { get; set; }
25
- }
26
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
LibraryManagement.Backend/Features/Auth/AuthService.cs DELETED
@@ -1,110 +0,0 @@
1
- using Database.Models;
2
- using Microsoft.EntityFrameworkCore;
3
- using Microsoft.IdentityModel.Tokens;
4
- using System.IdentityModel.Tokens.Jwt;
5
- using System.Security.Claims;
6
- using System.Text;
7
-
8
- using LibraryManagement.Backend.Features.Subscriptions;
9
-
10
- namespace LibraryManagement.Backend.Features.Auth
11
- {
12
- public interface IAuthService
13
- {
14
- Task<AuthResponse> Register(RegisterRequest request);
15
- Task<AuthResponse> Login(LoginRequest request);
16
- }
17
-
18
- public class AuthService : IAuthService
19
- {
20
- private readonly LibraryManagementContext _context;
21
- private readonly IConfiguration _configuration;
22
- private readonly ISubscriptionService _subscriptionService;
23
-
24
- public AuthService(LibraryManagementContext context, IConfiguration configuration, ISubscriptionService subscriptionService)
25
- {
26
- _context = context;
27
- _configuration = configuration;
28
- _subscriptionService = subscriptionService;
29
- }
30
-
31
- public async Task<AuthResponse> Register(RegisterRequest request)
32
- {
33
- if (await _context.Users.AnyAsync(u => u.Email == request.Email))
34
- {
35
- throw new Exception("User already exists with this email.");
36
- }
37
-
38
- var user = new User
39
- {
40
- FullName = request.FullName,
41
- Email = request.Email,
42
- PhoneNumber = request.PhoneNumber,
43
- Address = request.Address,
44
- StudentId = request.StudentId,
45
- PasswordHash = BCrypt.Net.BCrypt.HashPassword(request.Password),
46
- Role = "Member", // Default role
47
- IsActive = true,
48
- CreatedAt = DateTime.UtcNow
49
- };
50
-
51
- _context.Users.Add(user);
52
- await _context.SaveChangesAsync();
53
-
54
- if (!string.IsNullOrEmpty(user.StudentId))
55
- {
56
- await _subscriptionService.SubscribeUserAsync(user.Id, 3); // 3 is "Basic Yearly"
57
- }
58
-
59
- return await AuthenticateUser(user);
60
- }
61
-
62
- public async Task<AuthResponse> Login(LoginRequest request)
63
- {
64
- var user = await _context.Users.FirstOrDefaultAsync(u => u.Email == request.Email);
65
-
66
- if (user == null || !BCrypt.Net.BCrypt.Verify(request.Password, user.PasswordHash))
67
- {
68
- throw new Exception("Invalid email or password.");
69
- }
70
-
71
- if (!user.IsActive)
72
- {
73
- throw new Exception("User account is deactivated.");
74
- }
75
-
76
- return await AuthenticateUser(user);
77
- }
78
-
79
- private async Task<AuthResponse> AuthenticateUser(User user)
80
- {
81
- var tokenHandler = new JwtSecurityTokenHandler();
82
- var key = Encoding.ASCII.GetBytes(_configuration["Jwt:Secret"] ?? "YourSuperSecretKeyForLibraryManagementSystem_AtLeast32CharsLong");
83
-
84
- var tokenDescriptor = new SecurityTokenDescriptor
85
- {
86
- Subject = new ClaimsIdentity(new[]
87
- {
88
- new Claim(ClaimTypes.NameIdentifier, user.Id.ToString()),
89
- new Claim(ClaimTypes.Email, user.Email),
90
- new Claim(ClaimTypes.Name, user.FullName),
91
- new Claim(ClaimTypes.Role, user.Role)
92
- }),
93
- Expires = DateTime.UtcNow.AddDays(7),
94
- SigningCredentials = new SigningCredentials(new SymmetricSecurityKey(key), SecurityAlgorithms.HmacSha256Signature),
95
- Issuer = _configuration["Jwt:Issuer"],
96
- Audience = _configuration["Jwt:Audience"]
97
- };
98
-
99
- var token = tokenHandler.CreateToken(tokenDescriptor);
100
-
101
- return new AuthResponse
102
- {
103
- Token = tokenHandler.WriteToken(token),
104
- FullName = user.FullName,
105
- Role = user.Role,
106
- Expiry = tokenDescriptor.Expires.Value
107
- };
108
- }
109
- }
110
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
LibraryManagement.Backend/Features/Books/BookController.cs DELETED
@@ -1,67 +0,0 @@
1
- using Microsoft.AspNetCore.Authorization;
2
- using Microsoft.AspNetCore.Mvc;
3
-
4
- namespace LibraryManagement.Backend.Features.Books
5
- {
6
- [ApiController]
7
- [Route("api/books")]
8
- public class BookController : ControllerBase
9
- {
10
- private readonly IBookService _bookService;
11
-
12
- public BookController(IBookService bookService)
13
- {
14
- _bookService = bookService;
15
- }
16
-
17
- [HttpGet]
18
- //[Authorize]
19
- public async Task<ActionResult<IEnumerable<BookDto>>> GetBooks()
20
- {
21
- var books = await _bookService.GetAllBooksAsync();
22
- return Ok(books);
23
- }
24
-
25
- [HttpGet("{id}")]
26
- //[Authorize]
27
- public async Task<ActionResult<BookDto>> GetBook(int id)
28
- {
29
- var book = await _bookService.GetBookByIdAsync(id);
30
- if (book == null) return NotFound();
31
- return Ok(book);
32
- }
33
-
34
- [HttpPost]
35
- //[Authorize(Roles = "Librarian")]
36
- public async Task<ActionResult<BookDto>> CreateBook([FromBody] BookCreateRequest request)
37
- {
38
- try
39
- {
40
- var book = await _bookService.CreateBookAsync(request);
41
- return CreatedAtAction(nameof(GetBook), new { id = book.Id }, book);
42
- }
43
- catch (Exception ex)
44
- {
45
- return BadRequest(new { message = ex.Message });
46
- }
47
- }
48
-
49
- [HttpPut("{id}")]
50
- //[Authorize(Roles = "Librarian")]
51
- public async Task<ActionResult<BookDto>> UpdateBook(int id, [FromBody] BookUpdateRequest request)
52
- {
53
- var updatedBook = await _bookService.UpdateBookAsync(id, request);
54
- if (updatedBook == null) return NotFound();
55
- return Ok(updatedBook);
56
- }
57
-
58
- [HttpDelete("{id}")]
59
- //[Authorize(Roles = "Librarian")]
60
- public async Task<IActionResult> DeleteBook(int id)
61
- {
62
- var success = await _bookService.DeleteBookAsync(id);
63
- if (!success) return NotFound();
64
- return NoContent();
65
- }
66
- }
67
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
LibraryManagement.Backend/Features/Books/BookService.cs DELETED
@@ -1,150 +0,0 @@
1
- using Database.Models;
2
- using Microsoft.EntityFrameworkCore;
3
-
4
- namespace LibraryManagement.Backend.Features.Books
5
- {
6
- public interface IBookService
7
- {
8
- Task<IEnumerable<BookDto>> GetAllBooksAsync();
9
- Task<BookDto?> GetBookByIdAsync(int id);
10
- Task<BookDto> CreateBookAsync(BookCreateRequest request);
11
- Task<BookDto?> UpdateBookAsync(int id, BookUpdateRequest request);
12
- Task<bool> DeleteBookAsync(int id);
13
- }
14
-
15
- public class BookService : IBookService
16
- {
17
- private readonly LibraryManagementContext _context;
18
-
19
- public BookService(LibraryManagementContext context)
20
- {
21
- _context = context;
22
- }
23
-
24
- public async Task<IEnumerable<BookDto>> GetAllBooksAsync()
25
- {
26
- return await _context.Books
27
- .Where(b => b.IsActive)
28
- .Select(b => MapToDto(b))
29
- .ToListAsync();
30
- }
31
-
32
- public async Task<BookDto?> GetBookByIdAsync(int id)
33
- {
34
- var book = await _context.Books.FindAsync(id);
35
- if (book == null || !book.IsActive) return null;
36
- return MapToDto(book);
37
- }
38
-
39
- public async Task<BookDto> CreateBookAsync(BookCreateRequest request)
40
- {
41
- if (await _context.Books.AnyAsync(b => b.Isbn == request.Isbn))
42
- {
43
- throw new Exception("A book with this ISBN already exists.");
44
- }
45
-
46
- var book = new Book
47
- {
48
- Title = request.Title,
49
- Isbn = request.Isbn,
50
- Author = request.Author,
51
- Description = request.Description,
52
- TotalCopies = request.TotalCopies,
53
- AvailableCopies = request.TotalCopies,
54
- Status = request.TotalCopies > 0 ? "Available" : "Out Of Stock",
55
- IsActive = true,
56
- CreatedAt = DateTime.UtcNow
57
- };
58
-
59
- _context.Books.Add(book);
60
- await _context.SaveChangesAsync();
61
-
62
- return MapToDto(book);
63
- }
64
-
65
- public async Task<BookDto?> UpdateBookAsync(int id, BookUpdateRequest request)
66
- {
67
- var book = await _context.Books.FindAsync(id);
68
- if (book == null || !book.IsActive) return null;
69
-
70
- book.Title = request.Title;
71
- book.Author = request.Author;
72
- book.Description = request.Description;
73
-
74
- // Basic logic to sync availability when total copies change
75
- int difference = request.TotalCopies - book.TotalCopies;
76
- book.TotalCopies = request.TotalCopies;
77
- book.AvailableCopies += difference;
78
-
79
- if (book.AvailableCopies < 0) book.AvailableCopies = 0;
80
- book.Status = book.AvailableCopies > 0 ? "Available" : "Out Of Stock";
81
-
82
- book.UpdatedAt = DateTime.UtcNow;
83
-
84
- await _context.SaveChangesAsync();
85
- return MapToDto(book);
86
- }
87
-
88
- public async Task<bool> DeleteBookAsync(int id)
89
- {
90
- var book = await _context.Books.FindAsync(id);
91
- if (book == null) return false;
92
-
93
- book.IsActive = false;
94
- book.UpdatedAt = DateTime.UtcNow;
95
-
96
- await _context.SaveChangesAsync();
97
- return true;
98
- }
99
-
100
- private static BookDto MapToDto(Book book)
101
- {
102
- return new BookDto
103
- {
104
- Id = book.Id,
105
- Title = book.Title,
106
- Isbn = book.Isbn,
107
- Author = book.Author,
108
- Status = book.Status,
109
- IsActive = book.IsActive,
110
- Description = book.Description,
111
- TotalCopies = book.TotalCopies,
112
- AvailableCopies = book.AvailableCopies,
113
- CreatedAt = book.CreatedAt,
114
- UpdatedAt = book.UpdatedAt
115
- };
116
- }
117
- }
118
-
119
- public class BookDto
120
- {
121
- public int Id { get; set; }
122
- public string Title { get; set; } = string.Empty;
123
- public string Isbn { get; set; } = string.Empty;
124
- public string Author { get; set; } = string.Empty;
125
- public string Status { get; set; } = string.Empty;
126
- public bool IsActive { get; set; }
127
- public string? Description { get; set; }
128
- public int TotalCopies { get; set; }
129
- public int AvailableCopies { get; set; }
130
- public DateTime CreatedAt { get; set; }
131
- public DateTime? UpdatedAt { get; set; }
132
- }
133
-
134
- public class BookCreateRequest
135
- {
136
- public string Title { get; set; } = string.Empty;
137
- public string Isbn { get; set; } = string.Empty;
138
- public string Author { get; set; } = string.Empty;
139
- public string? Description { get; set; }
140
- public int TotalCopies { get; set; }
141
- }
142
-
143
- public class BookUpdateRequest
144
- {
145
- public string Title { get; set; } = string.Empty;
146
- public string Author { get; set; } = string.Empty;
147
- public string? Description { get; set; }
148
- public int TotalCopies { get; set; }
149
- }
150
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
LibraryManagement.Backend/Features/Borrowing/BorrowingController.cs DELETED
@@ -1,72 +0,0 @@
1
- using Microsoft.AspNetCore.Authorization;
2
- using Microsoft.AspNetCore.Mvc;
3
- using System.Security.Claims;
4
-
5
- namespace LibraryManagement.Backend.Features.Borrowings
6
- {
7
- [ApiController]
8
- [Route("api/borrowings")]
9
- public class BorrowingController : ControllerBase
10
- {
11
- private readonly IBorrowingService _borrowingService;
12
-
13
- public BorrowingController(IBorrowingService borrowingService)
14
- {
15
- _borrowingService = borrowingService;
16
- }
17
-
18
- [HttpPost("borrow")]
19
- //[Authorize]
20
- public async Task<ActionResult<BorrowingDto>> BorrowBook([FromBody] BorrowRequest request)
21
- {
22
- try
23
- {
24
- var userIdStr = User.FindFirstValue(ClaimTypes.NameIdentifier);
25
- if (string.IsNullOrEmpty(userIdStr)) return Unauthorized();
26
-
27
- var userId = int.Parse(userIdStr);
28
- var borrowing = await _borrowingService.BorrowBookAsync(userId, request.BookId);
29
- return Ok(borrowing);
30
- }
31
- catch (Exception ex)
32
- {
33
- return BadRequest(new { message = ex.Message });
34
- }
35
- }
36
-
37
- [HttpPost("return/{id}")]
38
- //[Authorize(Roles = "Librarian")]
39
- public async Task<ActionResult<BorrowingDto>> ReturnBook(int id)
40
- {
41
- try
42
- {
43
- var borrowing = await _borrowingService.ReturnBookAsync(id);
44
- return Ok(borrowing);
45
- }
46
- catch (Exception ex)
47
- {
48
- return BadRequest(new { message = ex.Message });
49
- }
50
- }
51
-
52
- [HttpGet("me")]
53
- //[Authorize]
54
- public async Task<ActionResult<IEnumerable<BorrowingDto>>> GetMyBorrowings()
55
- {
56
- var userIdStr = User.FindFirstValue(ClaimTypes.NameIdentifier);
57
- if (string.IsNullOrEmpty(userIdStr)) return Unauthorized();
58
-
59
- var userId = int.Parse(userIdStr);
60
- var borrowings = await _borrowingService.GetUserBorrowingsAsync(userId);
61
- return Ok(borrowings);
62
- }
63
-
64
- [HttpGet]
65
- //[Authorize(Roles = "Librarian")]
66
- public async Task<ActionResult<IEnumerable<BorrowingDto>>> GetAllBorrowings()
67
- {
68
- var borrowings = await _borrowingService.GetAllBorrowingsAsync();
69
- return Ok(borrowings);
70
- }
71
- }
72
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
LibraryManagement.Backend/Features/Borrowing/BorrowingModels.cs DELETED
@@ -1,24 +0,0 @@
1
- using System;
2
-
3
- namespace LibraryManagement.Backend.Features.Borrowings
4
- {
5
- public class BorrowingDto
6
- {
7
- public int Id { get; set; }
8
- public int 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;
12
- public DateTime BorrowDate { get; set; }
13
- public DateTime DueDate { get; set; }
14
- public DateTime? ReturnDate { get; set; }
15
- public string Status { get; set; } = string.Empty;
16
- public decimal FineAmount { get; set; }
17
- public bool IsFinePaid { get; set; }
18
- }
19
-
20
- public class BorrowRequest
21
- {
22
- public int BookId { get; set; }
23
- }
24
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
LibraryManagement.Backend/Features/Borrowing/BorrowingService.cs DELETED
@@ -1,166 +0,0 @@
1
- using Database.Models;
2
- using Microsoft.EntityFrameworkCore;
3
-
4
- namespace LibraryManagement.Backend.Features.Borrowings
5
- {
6
- public interface IBorrowingService
7
- {
8
- Task<BorrowingDto> BorrowBookAsync(int userId, int bookId);
9
- Task<BorrowingDto> ReturnBookAsync(int borrowingId);
10
- Task<IEnumerable<BorrowingDto>> GetUserBorrowingsAsync(int userId);
11
- Task<IEnumerable<BorrowingDto>> GetAllBorrowingsAsync();
12
- }
13
-
14
- public class BorrowingService : IBorrowingService
15
- {
16
- private readonly LibraryManagementContext _context;
17
- private const decimal FinePerDay = 500;
18
-
19
- public BorrowingService(LibraryManagementContext context)
20
- {
21
- _context = context;
22
- }
23
-
24
- public async Task<BorrowingDto> BorrowBookAsync(int userId, int bookId)
25
- {
26
- // 1. Check for Active Membership
27
- var subscription = await _context.UserSubscriptions
28
- .Include(s => s.Membership)
29
- .Where(s => s.UserId == userId && s.IsActive && s.ExpiryDate > DateTime.UtcNow)
30
- .FirstOrDefaultAsync();
31
-
32
- if (subscription == null)
33
- {
34
- throw new Exception("Active membership required to borrow books.");
35
- }
36
-
37
- // 2. Check for Overdue Books or Unpaid Fines
38
- var hasBlockers = await _context.Borrowings
39
- .AnyAsync(b => b.UserId == userId &&
40
- ((b.Status == "Borrowed" && b.DueDate < DateTime.UtcNow) || (b.FineAmount > 0 && !b.IsFinePaid)));
41
-
42
- if (hasBlockers)
43
- {
44
- throw new Exception("Borrowing blocked: You have overdue books or unpaid fines.");
45
- }
46
-
47
- // 3. Check MaxBooks limit
48
- var activeBorrowCount = await _context.Borrowings
49
- .CountAsync(b => b.UserId == userId && b.Status == "Borrowed");
50
-
51
- if (activeBorrowCount >= subscription.Membership.MaxBooks)
52
- {
53
- throw new Exception($"Borrowing limit reached: You can only borrow {subscription.Membership.MaxBooks} books at a time.");
54
- }
55
-
56
- // 4. Check Book Availability
57
- var book = await _context.Books.FindAsync(bookId);
58
- if (book == null || !book.IsActive || book.AvailableCopies <= 0)
59
- {
60
- throw new Exception("Book is currently unavailable.");
61
- }
62
-
63
- // 5. Create Borrowing Record
64
- var borrowing = new Borrowing
65
- {
66
- UserId = userId,
67
- BookId = bookId,
68
- BorrowDate = DateTime.UtcNow,
69
- DueDate = DateTime.UtcNow.AddDays(subscription.Membership.BorrowingDays),
70
- Status = "Borrowed",
71
- FineAmount = 0,
72
- IsFinePaid = false
73
- };
74
-
75
- // 6. Update Book Stock
76
- book.AvailableCopies--;
77
- if (book.AvailableCopies == 0)
78
- {
79
- book.Status = "Out Of Stock";
80
- }
81
-
82
- _context.Borrowings.Add(borrowing);
83
- await _context.SaveChangesAsync();
84
-
85
- // Load relations for mapping
86
- await _context.Entry(borrowing).Reference(b => b.Book).LoadAsync();
87
- await _context.Entry(borrowing).Reference(b => b.User).LoadAsync();
88
-
89
- return MapToDto(borrowing);
90
- }
91
-
92
- public async Task<BorrowingDto> ReturnBookAsync(int borrowingId)
93
- {
94
- var borrowing = await _context.Borrowings
95
- .Include(b => b.Book)
96
- .Include(b => b.User)
97
- .FirstOrDefaultAsync(b => b.Id == borrowingId);
98
-
99
- if (borrowing == null) throw new Exception("Borrowing record not found.");
100
- if (borrowing.Status == "Returned") throw new Exception("Book has already been returned.");
101
-
102
- var now = DateTime.UtcNow;
103
- borrowing.ReturnDate = now;
104
- borrowing.Status = "Returned";
105
-
106
- // Calculate Fine
107
- if (now > borrowing.DueDate)
108
- {
109
- var overdueDays = (now.Date - borrowing.DueDate.Date).Days;
110
- if (overdueDays > 0)
111
- {
112
- borrowing.FineAmount = overdueDays * FinePerDay;
113
- }
114
- }
115
-
116
- // Update Book Stock
117
- var book = borrowing.Book;
118
- book.AvailableCopies++;
119
- book.Status = "Available";
120
-
121
- await _context.SaveChangesAsync();
122
- return MapToDto(borrowing);
123
- }
124
-
125
- public async Task<IEnumerable<BorrowingDto>> GetUserBorrowingsAsync(int userId)
126
- {
127
- var borrowings = await _context.Borrowings
128
- .Include(b => b.Book)
129
- .Include(b => b.User)
130
- .Where(b => b.UserId == userId)
131
- .OrderByDescending(b => b.BorrowDate)
132
- .ToListAsync();
133
-
134
- return borrowings.Select(MapToDto);
135
- }
136
-
137
- public async Task<IEnumerable<BorrowingDto>> GetAllBorrowingsAsync()
138
- {
139
- var borrowings = await _context.Borrowings
140
- .Include(b => b.Book)
141
- .Include(b => b.User)
142
- .OrderByDescending(b => b.BorrowDate)
143
- .ToListAsync();
144
-
145
- return borrowings.Select(MapToDto);
146
- }
147
-
148
- private static BorrowingDto MapToDto(Borrowing b)
149
- {
150
- return new BorrowingDto
151
- {
152
- Id = b.Id,
153
- UserId = b.UserId,
154
- UserEmail = b.User?.Email ?? "Unknown",
155
- BookId = b.BookId,
156
- BookTitle = b.Book?.Title ?? "Unknown",
157
- BorrowDate = b.BorrowDate,
158
- DueDate = b.DueDate,
159
- ReturnDate = b.ReturnDate,
160
- Status = b.Status,
161
- FineAmount = b.FineAmount,
162
- IsFinePaid = b.IsFinePaid
163
- };
164
- }
165
- }
166
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
LibraryManagement.Backend/Features/Categories/CategoryController.cs DELETED
@@ -1,49 +0,0 @@
1
- using Microsoft.AspNetCore.Authorization;
2
- using Microsoft.AspNetCore.Mvc;
3
-
4
- namespace LibraryManagement.Backend.Features.Categories
5
- {
6
- [ApiController]
7
- [Route("api/categories")]
8
- public class CategoryController : ControllerBase
9
- {
10
- private readonly ICategoryService _categoryService;
11
-
12
- public CategoryController(ICategoryService categoryService)
13
- {
14
- _categoryService = categoryService;
15
- }
16
-
17
- [HttpGet]
18
- //[Authorize] // Accessible by both Librarian and Member
19
- public async Task<ActionResult<IEnumerable<CategoryDto>>> GetCategories()
20
- {
21
- var categories = await _categoryService.GetAllCategoriesAsync();
22
- return Ok(categories);
23
- }
24
-
25
- [HttpPost]
26
- //[Authorize(Roles = "Librarian")]
27
- public async Task<ActionResult<CategoryDto>> CreateCategory([FromBody] CategoryCreateRequest request)
28
- {
29
- try
30
- {
31
- var category = await _categoryService.CreateCategoryAsync(request);
32
- return CreatedAtAction(nameof(GetCategories), category);
33
- }
34
- catch (Exception ex)
35
- {
36
- return BadRequest(new { message = ex.Message });
37
- }
38
- }
39
-
40
- [HttpDelete("{id}")]
41
- //[Authorize(Roles = "Librarian")]
42
- public async Task<IActionResult> DeleteCategory(int id)
43
- {
44
- var success = await _categoryService.DeleteCategoryAsync(id);
45
- if (!success) return NotFound();
46
- return NoContent();
47
- }
48
- }
49
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
LibraryManagement.Backend/Features/Categories/CategoryService.cs DELETED
@@ -1,69 +0,0 @@
1
- using Database.Models;
2
- using Microsoft.EntityFrameworkCore;
3
-
4
- namespace LibraryManagement.Backend.Features.Categories
5
- {
6
- public interface ICategoryService
7
- {
8
- Task<IEnumerable<CategoryDto>> GetAllCategoriesAsync();
9
- Task<CategoryDto> CreateCategoryAsync(CategoryCreateRequest request);
10
- Task<bool> DeleteCategoryAsync(int id);
11
- }
12
-
13
- public class CategoryService : ICategoryService
14
- {
15
- private readonly LibraryManagementContext _context;
16
-
17
- public CategoryService(LibraryManagementContext context)
18
- {
19
- _context = context;
20
- }
21
-
22
- public async Task<IEnumerable<CategoryDto>> GetAllCategoriesAsync()
23
- {
24
- return await _context.Categories
25
- .Select(c => new CategoryDto { Id = c.Id, Name = c.Name })
26
- .ToListAsync();
27
- }
28
-
29
- public async Task<CategoryDto> CreateCategoryAsync(CategoryCreateRequest request)
30
- {
31
- if (await _context.Categories.AnyAsync(c => c.Name == request.Name))
32
- {
33
- throw new Exception("Category with this name already exists.");
34
- }
35
-
36
- var category = new Category
37
- {
38
- Name = request.Name
39
- };
40
-
41
- _context.Categories.Add(category);
42
- await _context.SaveChangesAsync();
43
-
44
- return new CategoryDto { Id = category.Id, Name = category.Name };
45
- }
46
-
47
- public async Task<bool> DeleteCategoryAsync(int id)
48
- {
49
- var category = await _context.Categories.FindAsync(id);
50
- if (category == null) return false;
51
-
52
- // Note: EF automatically handles removing associations in many-to-many join tables
53
- _context.Categories.Remove(category);
54
- await _context.SaveChangesAsync();
55
- return true;
56
- }
57
- }
58
-
59
- public class CategoryDto
60
- {
61
- public int Id { get; set; }
62
- public string Name { get; set; } = string.Empty;
63
- }
64
-
65
- public class CategoryCreateRequest
66
- {
67
- public string Name { get; set; } = string.Empty;
68
- }
69
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
LibraryManagement.Backend/Features/Subscriptions/SubscriptionController.cs DELETED
@@ -1,84 +0,0 @@
1
- using Microsoft.AspNetCore.Authorization;
2
- using Microsoft.AspNetCore.Mvc;
3
- using System.Security.Claims;
4
-
5
- namespace LibraryManagement.Backend.Features.Subscriptions
6
- {
7
- [ApiController]
8
- [Route("api")]
9
- public class SubscriptionController : ControllerBase
10
- {
11
- private readonly ISubscriptionService _subscriptionService;
12
-
13
- public SubscriptionController(ISubscriptionService subscriptionService)
14
- {
15
- _subscriptionService = subscriptionService;
16
- }
17
-
18
- [HttpGet("memberships")]
19
- [AllowAnonymous]
20
- public async Task<ActionResult<IEnumerable<MembershipDto>>> GetMemberships()
21
- {
22
- return Ok(await _subscriptionService.GetMembershipsAsync());
23
- }
24
-
25
- [HttpGet("subscriptions/me")]
26
- [Authorize]
27
- public async Task<ActionResult<SubscriptionDto>> GetMySubscription()
28
- {
29
- var userIdStr = User.FindFirstValue(ClaimTypes.NameIdentifier);
30
- if (string.IsNullOrEmpty(userIdStr)) return Unauthorized();
31
-
32
- var userId = int.Parse(userIdStr);
33
- var subscription = await _subscriptionService.GetUserSubscriptionAsync(userId);
34
-
35
- if (subscription == null) return NotFound(new { message = "No active subscription found." });
36
-
37
- return Ok(subscription);
38
- }
39
-
40
- [HttpPost("subscriptions/subscribe")]
41
- [Authorize]
42
- public async Task<ActionResult<SubscriptionDto>> Subscribe([FromBody] SubscribeRequest request)
43
- {
44
- try
45
- {
46
- var userIdStr = User.FindFirstValue(ClaimTypes.NameIdentifier);
47
- if (string.IsNullOrEmpty(userIdStr)) return Unauthorized();
48
-
49
- var userId = int.Parse(userIdStr);
50
- var subscription = await _subscriptionService.SubscribeUserAsync(userId, request.MembershipId);
51
- return Ok(subscription);
52
- }
53
- catch (Exception ex)
54
- {
55
- return BadRequest(new { message = ex.Message });
56
- }
57
- }
58
-
59
- [HttpGet("subscriptions/user/{userId}")]
60
- [Authorize(Roles = "Admin")]
61
- public async Task<ActionResult<SubscriptionDto>> GetUserSubscription(int userId)
62
- {
63
- var subscription = await _subscriptionService.GetUserSubscriptionAsync(userId);
64
- if (subscription == null) return NotFound(new { message = "No active subscription found." });
65
-
66
- return Ok(subscription);
67
- }
68
-
69
- [HttpPost("subscriptions/admin-subscribe")]
70
- [Authorize(Roles = "Admin")]
71
- public async Task<ActionResult<SubscriptionDto>> AdminSubscribe([FromBody] AdminSubscribeRequest request)
72
- {
73
- try
74
- {
75
- var subscription = await _subscriptionService.SubscribeUserAsync(request.UserId, request.MembershipId);
76
- return Ok(subscription);
77
- }
78
- catch (Exception ex)
79
- {
80
- return BadRequest(new { message = ex.Message });
81
- }
82
- }
83
- }
84
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
LibraryManagement.Backend/Features/Subscriptions/SubscriptionModels.cs DELETED
@@ -1,38 +0,0 @@
1
- using System;
2
-
3
- namespace LibraryManagement.Backend.Features.Subscriptions
4
- {
5
- public class MembershipDto
6
- {
7
- public int Id { get; set; }
8
- public string Type { get; set; } = string.Empty;
9
- public int MaxBooks { get; set; }
10
- public int BorrowingDays { get; set; }
11
- public decimal Price { get; set; }
12
- public string Currency { get; set; } = "MMK";
13
- public int DurationMonths { get; set; }
14
- }
15
-
16
- public class SubscriptionDto
17
- {
18
- public int Id { get; set; }
19
- public int UserId { get; set; }
20
- public int MembershipId { get; set; }
21
- public string MembershipType { get; set; } = string.Empty;
22
- public DateTime StartDate { get; set; }
23
- public DateTime ExpiryDate { get; set; }
24
- public bool IsActive { get; set; }
25
- public bool IsExpired => DateTime.UtcNow > ExpiryDate;
26
- }
27
-
28
- public class SubscribeRequest
29
- {
30
- public int MembershipId { get; set; }
31
- }
32
-
33
- public class AdminSubscribeRequest
34
- {
35
- public int UserId { get; set; }
36
- public int MembershipId { get; set; }
37
- }
38
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
LibraryManagement.Backend/Features/Subscriptions/SubscriptionService.cs DELETED
@@ -1,96 +0,0 @@
1
- using Database.Models;
2
- using Microsoft.EntityFrameworkCore;
3
-
4
- namespace LibraryManagement.Backend.Features.Subscriptions
5
- {
6
- public interface ISubscriptionService
7
- {
8
- Task<IEnumerable<MembershipDto>> GetMembershipsAsync();
9
- Task<SubscriptionDto?> GetUserSubscriptionAsync(int userId);
10
- Task<SubscriptionDto> SubscribeUserAsync(int userId, int membershipId);
11
- }
12
-
13
- public class SubscriptionService : ISubscriptionService
14
- {
15
- private readonly LibraryManagementContext _context;
16
-
17
- public SubscriptionService(LibraryManagementContext context)
18
- {
19
- _context = context;
20
- }
21
-
22
- public async Task<IEnumerable<MembershipDto>> GetMembershipsAsync()
23
- {
24
- return await _context.Memberships
25
- .Select(m => new MembershipDto
26
- {
27
- Id = m.Id,
28
- Type = m.Type,
29
- MaxBooks = m.MaxBooks,
30
- BorrowingDays = m.BorrowingDays,
31
- Price = m.Price,
32
- DurationMonths = m.DurationMonths
33
- }).ToListAsync();
34
- }
35
-
36
- public async Task<SubscriptionDto?> GetUserSubscriptionAsync(int userId)
37
- {
38
- var subscription = await _context.UserSubscriptions
39
- .Include(s => s.Membership)
40
- .Where(s => s.UserId == userId && s.IsActive)
41
- .OrderByDescending(s => s.StartDate)
42
- .FirstOrDefaultAsync();
43
-
44
- if (subscription == null) return null;
45
-
46
- return MapToDto(subscription);
47
- }
48
-
49
- public async Task<SubscriptionDto> SubscribeUserAsync(int userId, int membershipId)
50
- {
51
- var membership = await _context.Memberships.FindAsync(membershipId);
52
- if (membership == null) throw new Exception("Membership plan not found.");
53
-
54
- // Deactivate any existing active subscriptions for this user
55
- var activeSubscriptions = await _context.UserSubscriptions
56
- .Where(s => s.UserId == userId && s.IsActive)
57
- .ToListAsync();
58
-
59
- foreach (var s in activeSubscriptions)
60
- {
61
- s.IsActive = false;
62
- }
63
-
64
- var subscription = new UserSubscription
65
- {
66
- UserId = userId,
67
- MembershipId = membershipId,
68
- StartDate = DateTime.UtcNow,
69
- ExpiryDate = DateTime.UtcNow.AddMonths(membership.DurationMonths),
70
- IsActive = true
71
- };
72
-
73
- _context.UserSubscriptions.Add(subscription);
74
- await _context.SaveChangesAsync();
75
-
76
- // Explicitly load the membership data for the DTO mapping
77
- await _context.Entry(subscription).Reference(s => s.Membership).LoadAsync();
78
-
79
- return MapToDto(subscription);
80
- }
81
-
82
- private static SubscriptionDto MapToDto(UserSubscription subscription)
83
- {
84
- return new SubscriptionDto
85
- {
86
- Id = subscription.Id,
87
- UserId = subscription.UserId,
88
- MembershipId = subscription.MembershipId,
89
- MembershipType = subscription.Membership.Type,
90
- StartDate = subscription.StartDate,
91
- ExpiryDate = subscription.ExpiryDate,
92
- IsActive = subscription.IsActive
93
- };
94
- }
95
- }
96
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
LibraryManagement.Backend/Features/Users/UserController.cs DELETED
@@ -1,77 +0,0 @@
1
- using Microsoft.AspNetCore.Authorization;
2
- using Microsoft.AspNetCore.Mvc;
3
-
4
- namespace LibraryManagement.Backend.Features.Users
5
- {
6
- [ApiController]
7
- [Route("api/users")]
8
- public class UserController : ControllerBase
9
- {
10
- private readonly IUserService _userService;
11
-
12
- public UserController(IUserService userService)
13
- {
14
- _userService = userService;
15
- }
16
-
17
- [HttpGet]
18
- //[Authorize(Roles = "Librarian")]
19
- public async Task<ActionResult<IEnumerable<UserDto>>> GetUsers()
20
- {
21
- var users = await _userService.GetAllUsersAsync();
22
- return Ok(users);
23
- }
24
-
25
- [HttpGet("{id}")]
26
- //[Authorize(Roles = "Librarian")]
27
- public async Task<ActionResult<UserDto>> GetUser(int id)
28
- {
29
- var user = await _userService.GetUserByIdAsync(id);
30
- if (user == null) return NotFound();
31
- return Ok(user);
32
- }
33
-
34
- [HttpPost]
35
- [AllowAnonymous]
36
- public async Task<ActionResult<UserDto>> CreateUser([FromBody] UserCreateRequest request)
37
- {
38
- try
39
- {
40
- var response = await _userService.CreateUserAsync(request);
41
- return CreatedAtAction(nameof(GetUser), new { id = response.Id }, response);
42
- }
43
- catch (Exception ex)
44
- {
45
- return BadRequest(new { message = ex.Message });
46
- }
47
- }
48
-
49
- [HttpPut("{id}")]
50
- //[Authorize(Roles = "Librarian")]
51
- public async Task<ActionResult<UserDto>> UpdateUser(int id, [FromBody] UserUpdateRequest request)
52
- {
53
- var updatedUser = await _userService.UpdateUserAsync(id, request);
54
- if (updatedUser == null) return NotFound();
55
- return Ok(updatedUser);
56
- }
57
-
58
- [HttpPatch("{id}/role")]
59
- //[Authorize(Roles = "Librarian")]
60
- public async Task<IActionResult> UpdateUserRole(int id, [FromBody] UserRoleUpdateRequest request)
61
- {
62
- var success = await _userService.UpdateUserRoleAsync(id, request.Role);
63
- if (!success) return NotFound();
64
- return NoContent();
65
- }
66
-
67
- [HttpDelete("{id}")]
68
- //[Authorize(Roles = "Librarian")]
69
- public async Task<IActionResult> DeleteUser(int id)
70
- {
71
- var success = await _userService.DeleteUserAsync(id);
72
- if (!success) return NotFound();
73
- return NoContent();
74
- }
75
- }
76
- }
77
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
LibraryManagement.Backend/Features/Users/UserService.cs DELETED
@@ -1,182 +0,0 @@
1
- using Database.Models;
2
- using Microsoft.EntityFrameworkCore;
3
- using LibraryManagement.Backend.Features.Subscriptions;
4
- using System;
5
- using System.Collections.Generic;
6
- using System.Linq;
7
- using System.Threading.Tasks;
8
-
9
- namespace LibraryManagement.Backend.Features.Users
10
- {
11
- public interface IUserService
12
- {
13
- Task<IEnumerable<UserDto>> GetAllUsersAsync();
14
- Task<UserDto?> GetUserByIdAsync(int id);
15
- Task<UserDto> CreateUserAsync(UserCreateRequest request);
16
- Task<UserDto?> UpdateUserAsync(int id, UserUpdateRequest request);
17
- Task<bool> UpdateUserRoleAsync(int id, string role);
18
- Task<bool> DeleteUserAsync(int id);
19
- }
20
-
21
- public class UserService : IUserService
22
- {
23
- private readonly LibraryManagementContext _context;
24
- private readonly ISubscriptionService _subscriptionService;
25
-
26
- public UserService(LibraryManagementContext context, ISubscriptionService subscriptionService)
27
- {
28
- _context = context;
29
- _subscriptionService = subscriptionService;
30
- }
31
-
32
- public async Task<IEnumerable<UserDto>> GetAllUsersAsync()
33
- {
34
- var users = await _context.Users.ToListAsync();
35
- return users.Select(MapToDto);
36
- }
37
-
38
- public async Task<UserDto?> GetUserByIdAsync(int id)
39
- {
40
- var user = await _context.Users.FindAsync(id);
41
- return user == null ? null : MapToDto(user);
42
- }
43
-
44
- public async Task<UserDto> CreateUserAsync(UserCreateRequest request)
45
- {
46
- if (await _context.Users.AnyAsync(u => u.Email == request.Email))
47
- {
48
- throw new Exception("Email already registered.");
49
- }
50
-
51
- var user = new User
52
- {
53
- FullName = request.FullName,
54
- Email = request.Email,
55
- PasswordHash = BCrypt.Net.BCrypt.HashPassword(request.Password),
56
- PhoneNumber = request.PhoneNumber,
57
- Address = request.Address,
58
- StudentId = request.StudentId,
59
- Role = "Member", // Default role
60
- IsActive = true,
61
- CreatedAt = DateTime.UtcNow
62
- };
63
-
64
- _context.Users.Add(user);
65
- await _context.SaveChangesAsync();
66
-
67
- if (!string.IsNullOrEmpty(user.StudentId))
68
- {
69
- await _subscriptionService.SubscribeUserAsync(user.Id, 3); // 3 is "Basic Yearly"
70
- }
71
-
72
- return MapToDto(user);
73
- }
74
-
75
- public async Task<UserDto?> UpdateUserAsync(int id, UserUpdateRequest request)
76
- {
77
- var user = await _context.Users.FindAsync(id);
78
- if (user == null) return null;
79
-
80
- bool isNewlyStudent = string.IsNullOrEmpty(user.StudentId) && !string.IsNullOrEmpty(request.StudentId);
81
-
82
- user.FullName = request.FullName;
83
- user.PhoneNumber = request.PhoneNumber;
84
- user.Address = request.Address;
85
- user.StudentId = request.StudentId;
86
- user.UpdatedAt = DateTime.UtcNow;
87
-
88
- await _context.SaveChangesAsync();
89
-
90
- if (isNewlyStudent)
91
- {
92
- await _subscriptionService.SubscribeUserAsync(user.Id, 3);
93
- }
94
-
95
- return MapToDto(user);
96
- }
97
-
98
- public async Task<bool> UpdateUserRoleAsync(int id, string role)
99
- {
100
- var user = await _context.Users.FindAsync(id);
101
- if (user == null) return false;
102
-
103
- user.Role = role;
104
- user.UpdatedAt = DateTime.UtcNow;
105
-
106
- await _context.SaveChangesAsync();
107
- return true;
108
- }
109
-
110
- public async Task<bool> DeleteUserAsync(int id)
111
- {
112
- var user = await _context.Users.FindAsync(id);
113
- if (user == null) return false;
114
-
115
- // Soft delete
116
- user.IsActive = false;
117
- user.UpdatedAt = DateTime.UtcNow;
118
-
119
- await _context.SaveChangesAsync();
120
- return true;
121
- }
122
-
123
- private static UserDto MapToDto(User user)
124
- {
125
- return new UserDto
126
- {
127
- Id = user.Id,
128
- FullName = user.FullName,
129
- Email = user.Email,
130
- PhoneNumber = user.PhoneNumber,
131
- Role = user.Role,
132
- IsActive = user.IsActive,
133
- StudentId = user.StudentId,
134
- Address = user.Address,
135
- CreatedAt = user.CreatedAt,
136
- UpdatedAt = user.UpdatedAt,
137
- BanStatus = user.BanStatus,
138
- SuspensionEndDate = user.SuspensionEndDate
139
- };
140
- }
141
- }
142
-
143
- public class UserDto
144
- {
145
- public int Id { get; set; }
146
- public string Name => FullName;
147
- public string FullName { get; set; } = string.Empty;
148
- public string Email { get; set; } = string.Empty;
149
- public string? PhoneNumber { get; set; }
150
- public string Role { get; set; } = string.Empty;
151
- public bool IsActive { get; set; }
152
- public string? StudentId { get; set; }
153
- public string? Address { get; set; }
154
- public DateTime CreatedAt { get; set; }
155
- public DateTime? UpdatedAt { get; set; }
156
- public bool? BanStatus { get; set; }
157
- public DateTime? SuspensionEndDate { get; set; }
158
- }
159
-
160
- public class UserCreateRequest
161
- {
162
- public string FullName { get; set; } = string.Empty;
163
- public string Email { get; set; } = string.Empty;
164
- public string Password { get; set; } = string.Empty;
165
- public string? PhoneNumber { get; set; }
166
- public string? StudentId { get; set; }
167
- public string? Address { get; set; }
168
- }
169
-
170
- public class UserUpdateRequest
171
- {
172
- public string FullName { get; set; } = string.Empty;
173
- public string? PhoneNumber { get; set; }
174
- public string? StudentId { get; set; }
175
- public string? Address { get; set; }
176
- }
177
-
178
- public class UserRoleUpdateRequest
179
- {
180
- public string Role { get; set; } = string.Empty;
181
- }
182
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
LibraryManagement.Backend/LibraryManagement.Backend.csproj DELETED
@@ -1,20 +0,0 @@
1
- <Project Sdk="Microsoft.NET.Sdk.Web">
2
-
3
- <PropertyGroup>
4
- <TargetFramework>net8.0</TargetFramework>
5
- <Nullable>enable</Nullable>
6
- <ImplicitUsings>enable</ImplicitUsings>
7
- </PropertyGroup>
8
-
9
- <ItemGroup>
10
- <PackageReference Include="BCrypt.Net-Next" Version="4.1.0" />
11
- <PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="8.0.13" />
12
- <PackageReference Include="Swashbuckle.AspNetCore" Version="6.6.2" />
13
- <PackageReference Include="System.IdentityModel.Tokens.Jwt" Version="8.17.0" />
14
- </ItemGroup>
15
-
16
- <ItemGroup>
17
- <ProjectReference Include="..\Database\Database.csproj" />
18
- </ItemGroup>
19
-
20
- </Project>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
LibraryManagement.Backend/LibraryManagement.Backend.http DELETED
@@ -1,6 +0,0 @@
1
- @LibraryManagement.Backend_HostAddress = http://localhost:5199
2
-
3
- GET {{LibraryManagement.Backend_HostAddress}}/weatherforecast/
4
- Accept: application/json
5
-
6
- ###
 
 
 
 
 
 
 
LibraryManagement.Backend/Program.cs DELETED
@@ -1,91 +0,0 @@
1
- using System.Text;
2
- using Database.Models;
3
- using LibraryManagement.Backend.Features.Auth;
4
- using LibraryManagement.Backend.Features.Users;
5
- using LibraryManagement.Backend.Features.Books;
6
- using Microsoft.AspNetCore.Authentication.JwtBearer;
7
- using Microsoft.EntityFrameworkCore;
8
- using Microsoft.IdentityModel.Tokens;
9
- using Microsoft.OpenApi.Models;
10
- using LibraryManagement.Backend.Features.Subscriptions;
11
- using LibraryManagement.Backend.Features.Categories;
12
- using LibraryManagement.Backend.Features.Borrowings;
13
-
14
- var builder = WebApplication.CreateBuilder(args);
15
-
16
- builder.Services.AddControllers();
17
- builder.Services.AddAuthorization();
18
- builder.Services.AddEndpointsApiExplorer();
19
- builder.Services.AddSwaggerGen(c =>
20
- {
21
- c.SwaggerDoc("v1", new OpenApiInfo { Title = "Library Management API", Version = "v1" });
22
- c.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme
23
- {
24
- Description = "JWT Authorization header using the Bearer scheme.",
25
- Name = "Authorization",
26
- In = ParameterLocation.Header,
27
- Type = SecuritySchemeType.Http,
28
- Scheme = "bearer",
29
- BearerFormat = "JWT"
30
- });
31
- c.AddSecurityRequirement(new OpenApiSecurityRequirement
32
- {
33
- {
34
- new OpenApiSecurityScheme
35
- {
36
- Reference = new OpenApiReference
37
- {
38
- Type = ReferenceType.SecurityScheme,
39
- Id = "Bearer"
40
- }
41
- },
42
- new string[] {}
43
- }
44
- });
45
- });
46
-
47
- builder.Services.AddDbContext<LibraryManagementContext>(options =>
48
- options.UseSqlServer(builder.Configuration.GetConnectionString("MssqlConnection")));
49
-
50
- // Register Services
51
- builder.Services.AddScoped<IAuthService, AuthService>();
52
- builder.Services.AddScoped<IUserService, UserService>();
53
- builder.Services.AddScoped<IBookService, BookService>();
54
- builder.Services.AddScoped<ISubscriptionService, SubscriptionService>();
55
- builder.Services.AddScoped<ICategoryService, CategoryService>();
56
- builder.Services.AddScoped<IBorrowingService, BorrowingService>();
57
-
58
- // Configure JWT Authentication
59
- var key = Encoding.ASCII.GetBytes(builder.Configuration["Jwt:Secret"] ?? "YourSuperSecretKeyForLibraryManagementSystem_AtLeast32CharsLong");
60
- builder.Services.AddAuthentication(x =>
61
- {
62
- x.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
63
- x.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
64
- })
65
- .AddJwtBearer(x =>
66
- {
67
- x.RequireHttpsMetadata = false;
68
- x.SaveToken = true;
69
- x.TokenValidationParameters = new TokenValidationParameters
70
- {
71
- ValidateIssuerSigningKey = true,
72
- IssuerSigningKey = new SymmetricSecurityKey(key),
73
- ValidateIssuer = true,
74
- ValidateAudience = true,
75
- ValidIssuer = builder.Configuration["Jwt:Issuer"],
76
- ValidAudience = builder.Configuration["Jwt:Audience"],
77
- ClockSkew = TimeSpan.Zero
78
- };
79
- });
80
-
81
- var app = builder.Build();
82
-
83
- app.UseSwagger();
84
- app.UseSwaggerUI();
85
- app.UseAuthentication();
86
- app.UseAuthorization();
87
-
88
- app.MapControllers();
89
-
90
- app.Run();
91
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
LibraryManagement.Backend/Properties/launchSettings.json DELETED
@@ -1,41 +0,0 @@
1
- {
2
- "$schema": "http://json.schemastore.org/launchsettings.json",
3
- "iisSettings": {
4
- "windowsAuthentication": false,
5
- "anonymousAuthentication": true,
6
- "iisExpress": {
7
- "applicationUrl": "http://localhost:13110",
8
- "sslPort": 44374
9
- }
10
- },
11
- "profiles": {
12
- "http": {
13
- "commandName": "Project",
14
- "dotnetRunMessages": true,
15
- "launchBrowser": true,
16
- "launchUrl": "swagger",
17
- "applicationUrl": "http://localhost:5001",
18
- "environmentVariables": {
19
- "ASPNETCORE_ENVIRONMENT": "Development"
20
- }
21
- },
22
- "https": {
23
- "commandName": "Project",
24
- "dotnetRunMessages": true,
25
- "launchBrowser": true,
26
- "launchUrl": "swagger",
27
- "applicationUrl": "https://localhost:7028;http://localhost:5199",
28
- "environmentVariables": {
29
- "ASPNETCORE_ENVIRONMENT": "Development"
30
- }
31
- },
32
- "IIS Express": {
33
- "commandName": "IISExpress",
34
- "launchBrowser": true,
35
- "launchUrl": "swagger",
36
- "environmentVariables": {
37
- "ASPNETCORE_ENVIRONMENT": "Development"
38
- }
39
- }
40
- }
41
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
LibraryManagement.Backend/WeatherForecast.cs DELETED
@@ -1,13 +0,0 @@
1
- namespace LibraryManagement.Backend
2
- {
3
- public class WeatherForecast
4
- {
5
- public DateOnly Date { get; set; }
6
-
7
- public int TemperatureC { get; set; }
8
-
9
- public int TemperatureF => 32 + (int)(TemperatureC / 0.5556);
10
-
11
- public string? Summary { get; set; }
12
- }
13
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
LibraryManagement.Backend/appsettings.Development.json DELETED
@@ -1,8 +0,0 @@
1
- {
2
- "Logging": {
3
- "LogLevel": {
4
- "Default": "Information",
5
- "Microsoft.AspNetCore": "Warning"
6
- }
7
- }
8
- }
 
 
 
 
 
 
 
 
 
LibraryManagement.Backend/appsettings.json DELETED
@@ -1,18 +0,0 @@
1
- {
2
- "Logging": {
3
- "LogLevel": {
4
- "Default": "Information",
5
- "Microsoft.AspNetCore": "Warning"
6
- }
7
- },
8
- "AllowedHosts": "*",
9
- "ConnectionStrings": {
10
- //"MssqlConnection": "Server=DESKTOP-BP9A061;Database=LibraryManagement;User Id=sa;Password=sasa@123;TrustServerCertificate=True;"
11
- "MssqlConnection": "Server=.;Database=LibraryManagement;User Id=sa;Password=sasa@123;TrustServerCertificate=True;"
12
- },
13
- "Jwt": {
14
- "Secret": "YourSuperSecretKeyForLibraryManagementSystem_AtLeast32CharsLong",
15
- "Issuer": "LibraryManagementSystem",
16
- "Audience": "LibraryManagementUsers"
17
- }
18
- }