# Task ID: 16

**Title:** Implement Locations CLI Commands

**Status:** pending

**Dependencies:** 8, 11, 15

**Priority:** medium

**Description:** Create the locations command group with list, show, and search commands reading from CSV cache.

**Details:**

Create `src/teams_phone/cli/locations.py`:
```python
locations_app = typer.Typer(name="locations", help="Emergency location management")

@locations_app.command("list")
def list_locations(ctx: typer.Context):
    """List all emergency locations from CSV cache."""
    # Show staleness warning if applicable
    # Display table with: description, address, city, state, isDefault
    ...

@locations_app.command()
def show(ctx: typer.Context, location: str = typer.Argument(..., help="Location ID or name")):
    """Show detailed information for a specific location."""
    ...

@locations_app.command()
def search(ctx: typer.Context, query: str = typer.Argument(..., help="Search query")):
    """Search locations by name, city, or address."""
    ...
```

Display staleness warning before output if cache > 30 days.

**Test Strategy:**

CLI tests with sample CSV: verify list output format, search returns matches, show displays full details, staleness warning appears when appropriate.

---

## Implementation Notes

### Session: 2026-01-29 23:58 - Agent: claude-opus-4-5-20251101

**Status:** Implemented

#### What Was Done
- Created `src/teams_phone/cli/locations.py` with `locations_app` Typer instance
- Implemented `list` command with `--city`, `--limit`, `--all` options
- Implemented `show` command with location argument (ID or description)
- Implemented `search` command with query argument and `--field`, `--limit` options
- Added staleness warning check before output in all commands
- Updated `src/teams_phone/cli/main.py` to import `locations_app` from new module
- Removed placeholder `locations_app` definition from main.py
- Created `tests/unit/test_cli_locations.py` with 31 unit tests covering all commands

#### Key Decisions Made
- **Synchronous service calls**: LocationService is synchronous (reads from CSV cache), unlike UserService which uses async Graph API calls. No async/await needed.
- **Search implementation**: Search uses the local list_locations() and filters in-memory rather than calling service.search_locations() to support the `--field` option which filters by specific fields.
- **City filter exact match**: The `--city` filter uses exact case-insensitive matching (equals), not partial matching (contains), to match the CLI spec behavior.
- **Field-specific search**: Added SearchField enum with `name`, `address`, `city`, `company` options matching the CLI specification.

#### Patterns Discovered
- **Model validation**: EmergencyLocation uses Pydantic aliases. For testing, use `model_validate()` with alias names (e.g., `locationId`) rather than attribute names to avoid mypy errors.
- **ANSI escape handling**: Test assertions for text with numeric values should check partial strings (e.g., "days old" instead of "45 days old") to avoid ANSI escape code issues.

#### Files Created/Modified
- Created: `src/teams_phone/cli/locations.py`
- Modified: `src/teams_phone/cli/main.py` (lines 13, 81-91)
- Created: `tests/unit/test_cli_locations.py`

#### Open Items for Next Agent
- None - task fully implemented

#### Gotchas and Warnings
- The test file uses `model_validate()` with a dict for EmergencyLocation to avoid mypy errors about alias field names
- Pre-existing failing test in `test_output_formatter.py::test_success_includes_checkmark` unrelated to this task

---
