# (DD20) Business Logic — Owner.addPet() [5 LOC]

| Field | Value |
|-------|-------|
| Fully Qualified Name | `org.springframework.samples.petclinic.owner.Owner` |
| Layer | Domain Model / Entity |
| Module | `owner` (Package: `org.springframework.samples.petclinic.owner`) |

## 1. Role

### Owner.addPet()

This method is the owner-side aggregation operation for the PetClinic domain model. It accepts a pet instance and adds it to the owner's in-memory pet collection only when the pet is new, which prevents duplicate association of an already-persisted pet into the same owner aggregate. In business terms, it supports pet enrollment for an owner record and acts as the domain-level gatekeeper for attaching a newly created pet to the owner profile.

The method implements a small routing/guard pattern: it checks the pet lifecycle state through `pet.isNew()` and either appends the pet to the owner's pet list or does nothing. There are no further branches, loops, or external service calls in this method. In the larger system, this method is used by controller flows that create pets and by update flows that may add a new pet when no existing pet record is found.

Because the method operates directly on the `pets` collection held by the `Owner` entity, it is part of the domain object consistency rules rather than a service-layer orchestration step. It is shared by multiple web flows and tests, making it a common domain helper for maintaining the owner-pet relationship.

## 2. Processing Pattern (Detailed Business Logic)

```mermaid
flowchart TD
    START(["addPet(pet)"])
    D1{"pet.isNew()?"}
    ADD["getPets().add(pet)"]
    END_NODE(["Return / Next"])
    START --> D1
    D1 -- "Yes" --> ADD
    D1 -- "No" --> END_NODE
    ADD --> END_NODE
```

## 3. Parameter Analysis

| No | Parameter Name | Type | Business Description |
|----|---------------|------|---------------------|
| 1 | `pet` | `Pet` | Pet aggregate member to be attached to the owner. It represents the pet being registered or introduced into the owner's profile. The method only adds it when the pet is in a new state, so existing persisted pets are not duplicated in the association list. |

**Instance fields / external state read by the method:** `pets` via `getPets()`, and the pet lifecycle flag via `pet.isNew()`.

## 4. CRUD Operations / Called Services

### Pre-computed evidence from code analysis graph:

| CRUD | SC / CBS | SC Code | Entity / DB | Operation Description |
|------|----------|---------|-------------|----------------------|
| R | `Owner.getPets` | Owner | - | Calls `getPets` in `Owner` |

Analyze all method calls within this method and classify each as a CRUD operation.

| CRUD | SC / CBS | SC Code | Entity / DB | Operation Description |
|------|----------|---------|-------------|----------------------|
| R | `pet.isNew` | Pet | `Pet` entity state | Reads the pet lifecycle flag to determine whether the pet has already been persisted. |
| R | `Owner.getPets` | Owner | `Owner.pets` collection | Reads the owner's current pet collection so the new pet can be appended when eligible. |
| C | `List.add` | `java.util.List` | `Owner.pets` collection | Adds a newly created pet into the owner's pet list, establishing the domain association. |

## 5. Dependency Trace

| # | Caller (Screen/Batch) | Call Chain (Full Path to this Method) | Terminal (SC / CRUD / Entity) |
|---|----------------------|--------------------------------------|-------------------------------|
| 1 | Screen:PetController | `PetController.initCreationForm` -> `Owner.addPet` | `List.add [C] Owner.pets` |
| 2 | Screen:PetController | `PetController.processCreationForm` -> `Owner.addPet` | `List.add [C] Owner.pets` |
| 3 | Screen:PetController | `PetController.updatePetDetails` -> `Owner.addPet` | `List.add [C] Owner.pets` |
| 4 | Test:PetControllerTests | `PetControllerTests` -> `Owner.addPet` | `List.add [C] Owner.pets` |
| 5 | Test:VisitControllerTests | `VisitControllerTests` -> `Owner.addPet` | `List.add [C] Owner.pets` |
| 6 | Test:OwnerControllerTests | `OwnerControllerTests` -> `Owner.addPet` | `List.add [C] Owner.pets` |
| 7 | Test:ClinicServiceTests | `ClinicServiceTests` -> `Owner.addPet` | `List.add [C] Owner.pets` |

## 6. Per-Branch Detail Blocks

**Block 1** — IF `(pet.isNew())` (L97)

> Guard clause that ensures only a brand-new pet is attached to the owner's collection.

| # | Type | Code |
|---|------|------|
| 1 | CALL | `pet.isNew()` |

**Block 1.1** — IF body `(pet.isNew() == true)` (L98)

| # | Type | Code |
|---|------|------|
| 1 | CALL | `getPets()` |
| 2 | EXEC | `getPets().add(pet);` |

**Block 1.2** — ELSE `(pet.isNew() == false)` (L97)

| # | Type | Code |
|---|------|------|
| 1 | RETURN | `return;` // no change to the owner-pet association |

## 7. Glossary

| Term | Type | Business Meaning |
|------|------|------------------|
| `Owner` | Domain entity | Customer or pet owner profile that holds personal details and the list of owned pets. |
| `Pet` | Domain entity | Animal record associated with an owner in the PetClinic business model. |
| `pets` | Field / Collection | The owner's pet roster maintained inside the owner aggregate. |
| `isNew` | Technical flag | Lifecycle check indicating whether the pet has not yet been persisted and should be treated as a new association. |
| `addPet` | Business operation | Adds a new pet to the owner's profile when the pet has not been persisted before. |
| `Owner.pets` | Relationship | One-to-many owner-to-pet association managed inside the domain object. |
| `Domain model` | Architecture term | Object model that enforces business rules directly in entities rather than in controllers or repositories. |
| `PetClinic` | Application name | Sample veterinary clinic system used to manage owners, pets, and visits. |
