From d3accc7e2fc2501ca9ab520f7d90381b6ef2f837 Mon Sep 17 00:00:00 2001 From: Sanjeev Kumar Nayak Date: Thu, 23 Jul 2026 21:53:15 -0700 Subject: [PATCH 1/2] new readme file added --- .../AccelerateDevGHCopilot/README.md | 69 +++++++++++++++++++ 1 file changed, 69 insertions(+) create mode 100644 LabFiles/02-analyze-document-code/AccelerateDevGHCopilot/README.md diff --git a/LabFiles/02-analyze-document-code/AccelerateDevGHCopilot/README.md b/LabFiles/02-analyze-document-code/AccelerateDevGHCopilot/README.md new file mode 100644 index 0000000..012e325 --- /dev/null +++ b/LabFiles/02-analyze-document-code/AccelerateDevGHCopilot/README.md @@ -0,0 +1,69 @@ +# Library App + +## Description + +Library App is a .NET console application for managing library operations such as patron search, loan tracking, membership renewals, and loan status updates. The application follows a layered architecture with separate domain, infrastructure, and console presentation components, and uses JSON files as its data store. + +## Project Structure + +- `AccelerateDevGHCopilot/` + - `src/` + - `Library.ApplicationCore/` + - `Entities/` - Domain models such as `Author`, `Book`, `BookItem`, `Loan`, and `Patron`. + - `Enums/` - Status enums used across the application. + - `Interfaces/` - Contracts for repositories and services. + - `Services/` - Business logic for library workflows. + - `Library.ApplicationCore.csproj` - Project file for the application core layer. + - `Library.Console/` + - `Program.cs` - Application startup and dependency injection wiring. + - `ConsoleApp.cs` - Main console flow and interaction logic. + - `CommonActions.cs` - Shared action options for the console UI. + - `ConsoleState.cs` - State management for the console app. + - `appSettings.json` - Runtime configuration. + - `Json/` - JSON seed data used by the sample app. + - `Library.Console.csproj` - Project file for the console application. + - `Library.Infrastructure/` + - `Data/` - JSON-backed repository implementations. + - `Library.Infrastructure.csproj` - Project file for the infrastructure layer. + - `tests/` + - `UnitTests/` - Unit tests that validate application behavior. + - `UnitTests.csproj` - Test project file. + +## Key Classes and Interfaces + +- `Patron` - Represents a library patron and membership information. +- `Loan` - Represents a loan transaction and associated dates. +- `Book` - Represents a book in the library catalog. +- `BookItem` - Represents an individual physical copy of a book. +- `Author` - Represents a book author. +- `IPatronRepository` - Defines patron data access operations. +- `ILoanRepository` - Defines loan data access operations. +- `IPatronService` - Defines patron business services. +- `ILoanService` - Defines loan business services. +- `PatronService` - Implements patron-related logic. +- `LoanService` - Implements loan-related logic. +- `JsonData` - Loads and saves JSON data and builds populated object graphs. +- `JsonPatronRepository` - Accesses patron records from JSON-backed storage. +- `JsonLoanRepository` - Accesses loan records from JSON-backed storage. +- `ConsoleApp` - Controls the main console user experience. + +## Usage + +1. Open the solution in Visual Studio Code. +2. Restore dependencies and build the solution: + ```bash + dotnet build + ``` +3. Run the console application: + ```bash + dotnet run --project src/Library.Console/Library.Console.csproj + ``` +4. Follow the interactive prompts to search for patrons, inspect loans, renew memberships, extend loans, and return books. +5. Run the unit tests: + ```bash + dotnet test tests/UnitTests/UnitTests.csproj + ``` + +## License + +This project is licensed under the MIT License. See the `LICENSE` file for details. \ No newline at end of file From 51378e303ef7d1d9db3f88525192d3f9436395fa Mon Sep 17 00:00:00 2001 From: Sanjeev Kumar Nayak Date: Thu, 23 Jul 2026 22:39:53 -0700 Subject: [PATCH 2/2] Add SearchBooks action to CommonActions and implement book availability check in ConsoleApp --- .../src/Library.Console/CommonActions.cs | 7 ++- .../src/Library.Console/ConsoleApp.cs | 62 ++++++++++++++++++- 2 files changed, 64 insertions(+), 5 deletions(-) diff --git a/LabFiles/02-analyze-document-code/AccelerateDevGHCopilot/src/Library.Console/CommonActions.cs b/LabFiles/02-analyze-document-code/AccelerateDevGHCopilot/src/Library.Console/CommonActions.cs index 681f95c..7bf4b69 100644 --- a/LabFiles/02-analyze-document-code/AccelerateDevGHCopilot/src/Library.Console/CommonActions.cs +++ b/LabFiles/02-analyze-document-code/AccelerateDevGHCopilot/src/Library.Console/CommonActions.cs @@ -7,7 +7,8 @@ public enum CommonActions Select = 1, Quit = 2, SearchPatrons = 4, - RenewPatronMembership = 8, - ReturnLoanedBook = 16, - ExtendLoanedBook = 32 + SearchBooks = 8, + RenewPatronMembership = 16, + ReturnLoanedBook = 32, + ExtendLoanedBook = 64 } diff --git a/LabFiles/02-analyze-document-code/AccelerateDevGHCopilot/src/Library.Console/ConsoleApp.cs b/LabFiles/02-analyze-document-code/AccelerateDevGHCopilot/src/Library.Console/ConsoleApp.cs index 9fc9750..7032067 100644 --- a/LabFiles/02-analyze-document-code/AccelerateDevGHCopilot/src/Library.Console/ConsoleApp.cs +++ b/LabFiles/02-analyze-document-code/AccelerateDevGHCopilot/src/Library.Console/ConsoleApp.cs @@ -2,6 +2,7 @@ using Library.ApplicationCore.Entities; using Library.ApplicationCore.Enums; using Library.Console; +using Library.Infrastructure.Data; public class ConsoleApp { @@ -16,13 +17,15 @@ public class ConsoleApp ILoanRepository _loanRepository; ILoanService _loanService; IPatronService _patronService; + JsonData _jsonData; - public ConsoleApp(ILoanService loanService, IPatronService patronService, IPatronRepository patronRepository, ILoanRepository loanRepository) + public ConsoleApp(ILoanService loanService, IPatronService patronService, IPatronRepository patronRepository, ILoanRepository loanRepository, JsonData jsonData) { _patronRepository = patronRepository; _loanRepository = loanRepository; _loanService = loanService; _patronService = patronService; + _jsonData = jsonData; } public async Task Run() @@ -136,6 +139,7 @@ static CommonActions ReadInputOptions(CommonActions options, out int optionNumbe { "q" when options.HasFlag(CommonActions.Quit) => CommonActions.Quit, "s" when options.HasFlag(CommonActions.SearchPatrons) => CommonActions.SearchPatrons, + "b" when options.HasFlag(CommonActions.SearchBooks) => CommonActions.SearchBooks, "m" when options.HasFlag(CommonActions.RenewPatronMembership) => CommonActions.RenewPatronMembership, "e" when options.HasFlag(CommonActions.ExtendLoanedBook) => CommonActions.ExtendLoanedBook, "r" when options.HasFlag(CommonActions.ReturnLoanedBook) => CommonActions.ReturnLoanedBook, @@ -170,6 +174,10 @@ static void WriteInputOptions(CommonActions options) { Console.WriteLine(" - \"s\" for new search"); } + if (options.HasFlag(CommonActions.SearchBooks)) + { + Console.WriteLine(" - \"b\" to check if a book is available for loan"); + } if (options.HasFlag(CommonActions.Quit)) { Console.WriteLine(" - \"q\" to quit"); @@ -193,7 +201,7 @@ async Task PatronDetails() loanNumber++; } - CommonActions options = CommonActions.SearchPatrons | CommonActions.Quit | CommonActions.Select | CommonActions.RenewPatronMembership; + CommonActions options = CommonActions.SearchPatrons | CommonActions.SearchBooks | CommonActions.Quit | CommonActions.Select | CommonActions.RenewPatronMembership; CommonActions action = ReadInputOptions(options, out int selectedLoanNumber); if (action == CommonActions.Select) { @@ -217,6 +225,10 @@ async Task PatronDetails() { return ConsoleState.PatronSearch; } + else if (action == CommonActions.SearchBooks) + { + return await SearchBooks(); + } else if (action == CommonActions.RenewPatronMembership) { var status = await _patronService.RenewMembership(selectedPatronDetails.Id); @@ -229,6 +241,52 @@ async Task PatronDetails() throw new InvalidOperationException("An input option is not handled."); } + async Task SearchBooks() + { + Console.Write("Enter a book title to search for: "); + string? searchInput = Console.ReadLine(); + + if (string.IsNullOrWhiteSpace(searchInput)) + { + Console.WriteLine("Please enter a valid title."); + return ConsoleState.PatronDetails; + } + + await _jsonData.EnsureDataLoaded(); + + var requestedBook = _jsonData.Books? + .FirstOrDefault(book => book.Title?.Contains(searchInput, StringComparison.OrdinalIgnoreCase) == true); + + if (requestedBook == null) + { + Console.WriteLine($"No matching book found for '{searchInput}'."); + return ConsoleState.PatronDetails; + } + + var matchingBookItem = _jsonData.BookItems? + .FirstOrDefault(bookItem => bookItem.BookId == requestedBook.Id); + + if (matchingBookItem == null) + { + Console.WriteLine($"{requestedBook.Title} is available for loan."); + return ConsoleState.PatronDetails; + } + + var activeLoan = _jsonData.Loans? + .FirstOrDefault(loan => loan.BookItemId == matchingBookItem.Id && loan.ReturnDate == null); + + if (activeLoan == null) + { + Console.WriteLine($"{requestedBook.Title} is available for loan."); + } + else + { + Console.WriteLine($"{requestedBook.Title} is on loan to another patron. The return due date is {activeLoan.DueDate}."); + } + + return ConsoleState.PatronDetails; + } + async Task LoanDetails() { Console.WriteLine($"Book title: {selectedLoanDetails.BookItem!.Book!.Title}");