# Model

## Overview

The `model` package contains the core domain objects for the library-style workflow in this codebase: books, members, and loans. These classes act as the in-memory representation of the system’s primary entities and carry just enough behavior to support borrowing and returning books.

This package appears to exist as a small, self-contained data model layer. It does not depend on any other package in the indexed code, and the classes communicate directly with each other through object references rather than through a separate persistence or service abstraction.

## Key Classes

### [Book](model/Book.java:3)

`Book` represents a single library item that can be borrowed. It stores identifying and descriptive metadata, plus an availability flag that reflects whether the book is currently available for checkout.

#### Responsibilities

- Hold the book’s identity and bibliographic details: `id`, `title`, `author`, and `isbn`.
- Track whether the book is currently available.
- Provide a string representation that is suitable for display in logs, lists, or console output.

#### Important methods

- [`Book.Book(String id, String title, String author, String isbn)`](model/Book.java:10)
  - Constructs a book with the supplied metadata.
  - Initializes `available` to `true`, so newly created books start in the borrowable state.
- [`Book.getId()`](model/Book.java:18), [`Book.getTitle()`](model/Book.java:19), [`Book.getAuthor()`](model/Book.java:20), [`Book.getIsbn()`](model/Book.java:21)
  - Standard accessors for the book fields.
  - Return the raw stored values without transformation.
- [`Book.isAvailable()`](model/Book.java:22)
  - Returns the current availability flag.
- [`Book.setAvailable(boolean available)`](model/Book.java:23)
  - Updates the availability flag.
  - This is the mechanism other model objects use to mark the book as borrowed or returned.
- [`Book.toString()`](model/Book.java:25)
  - Produces a human-readable summary in the form `[id] "title" by author (ISBN: isbn) - status`.
  - The status is derived from the availability flag and is rendered as `Available` or `Borrowed`.

#### Design notes

`Book` is intentionally lightweight. It does not enforce borrowing rules itself; instead, it exposes mutable availability so that `Loan` can coordinate state changes.

### [Member](model/Member.java:3)

`Member` represents a person who can borrow books. It is a simple identity and contact record with no workflow logic of its own.

#### Responsibilities

- Store the member’s identity and contact details: `id`, `name`, and `email`.
- Provide a concise string representation for display purposes.

#### Important methods

- [`Member.Member(String id, String name, String email)`](model/Member.java:8)
  - Creates a member record with the provided values.
- [`Member.getId()`](model/Member.java:14), [`Member.getName()`](model/Member.java:15), [`Member.getEmail()`](model/Member.java:16)
  - Standard getters for the member fields.
- [`Member.toString()`](model/Member.java:18)
  - Returns a formatted summary like `[id] name (email)`.

#### Design notes

`Member` is a pure data holder in this module. It does not participate in validation, authorization, or loan limits in the code that was provided.

### [Loan](model/Loan.java:5)

`Loan` links a `Book` to a `Member` and tracks the lifecycle of that borrowing transaction. It is the only class in this package that contains business state transitions beyond simple property storage.

#### Responsibilities

- Represent the association between one book and one member.
- Record when the loan was created and when it was returned.
- Update the book’s availability when the loan is returned.
- Provide a readable status string that reflects the loan lifecycle.

#### Important methods

- [`Loan.Loan(String id, Book book, Member member)`](model/Loan.java:13)
  - Creates a new loan for the supplied book and member.
  - Captures the current date in `borrowDate` using `LocalDate.now()`.
  - Marks the loan as not returned by setting `returned` to `false`.
- [`Loan.returnBook()`](model/Loan.java:21)
  - Records the current date in `returnDate`.
  - Marks the loan as returned.
  - Calls `book.setAvailable(true)` so the associated book becomes borrowable again.
- [`Loan.getId()`](model/Loan.java:27), [`Loan.getBook()`](model/Loan.java:28), [`Loan.getMember()`](model/Loan.java:29)
  - Accessors for the loan identity and linked entities.
- [`Loan.isReturned()`](model/Loan.java:30)
  - Returns whether the loan has been completed.
- [`Loan.toString()`](model/Loan.java:32)
  - Builds a summary string in the form `Loan[id] memberName -> "bookTitle" | status`.
  - If the loan has not been returned, the status shows the borrow date and explicitly notes that it is not returned.
  - If the loan has been returned, the status shows the return date.

#### Design notes

`Loan` is the bridge between `Book` and `Member`. Its `returnBook()` method is the key mutation point in the module because it coordinates loan state with book availability.

## How It Works

A typical borrow/return flow in this module looks like this:

1. A `Book` is created with descriptive metadata and starts as available.
2. A `Member` is created to represent the borrower.
3. A `Loan` is created to associate that member with that book.
4. The `Loan` records the borrow date and begins in the active, not-returned state.
5. When the book is returned, `Loan.returnBook()` marks the loan complete and flips the book back to available.

In practice, this means `Loan` owns the transaction state while `Book` owns the inventory state. The two are kept in sync manually through the `returnBook()` method.

```mermaid
flowchart LR
Book["Book"] --> Loan["Loan"]
Member["Member"] --> Loan
```

## Data Model

The package models three entities and one relationship:

- **Book**: identity plus bibliographic details, with mutable availability.
- **Member**: identity plus contact details.
- **Loan**: a transaction record that references one `Book` and one `Member`.

The `Loan` object stores two dates internally:

- `borrowDate` — set at construction time
- `returnDate` — set when `returnBook()` is called

The `returned` boolean is the primary state flag used to decide how the loan should be displayed and whether the return date should be shown.

## Dependencies and Integration

This module is intentionally isolated. Based on the indexed source, there are no resolved package dependencies and no cross-module relationships.

The only external API used directly in the code is `java.time.LocalDate` in `Loan`, which is used to capture borrow and return dates.

## Notes for Developers

- `Book` availability is mutable and is updated by `Loan.returnBook()`. If you add other code paths that change borrowing state, make sure they also keep the book’s `available` flag consistent.
- `Loan` does not currently prevent double-return behavior or validate whether a book was already available before construction. If stricter business rules are needed, they would need to be added explicitly.
- The `toString()` methods are designed for human-readable output, not structured serialization.
- The model classes use direct field access internally and provide only simple getters/setters. There is no immutability, validation layer, or persistence logic in this package.
