# GetProduct

## Overview

GetProduct retrieves a single product record by id or code. The input is a union type — callers specify exactly one lookup field. This serves as the core product lookup for existence checks, status validation, and all product lifecycle commands.

## Business Rules

- Accepts one of two lookup variants:
  - `{ id }` — retrieves by unique identifier (used for existence/state checks in lifecycle commands)
  - `{ code }` — retrieves by product code (used for uniqueness validation during creation; code is immutable after creation)
- Returns the full product record including all fields (id, code, name, description, unitId, status, timestamps)
- Returns null if no matching product is found
- All comparisons are exact (case-sensitive)

## Process Flow

```mermaid
flowchart TD
    A[Receive input] --> B{Which field?}
    B -->|id| C[SELECT from Product where id = input.id]
    B -->|code| D[SELECT from Product where code = input.code]
    C --> E{Product found?}
    D --> E
    E -->|Yes| F[Return product record]
    E -->|No| G[Return null]
```

## External Dependencies

- None

## Error Scenarios

- **PRODUCT_NOT_FOUND**: No product matches the given criteria — caller receives null

## Test Cases

- returns product when found
- returns null when not found
- returns product when found
- returns null when not found
