# Upgrading to v2

v2 is a full redesign of the library. This guide covers every breaking change
and how to migrate your code.

## Dependency

```elixir
# v1
{:logpoint_api, "~> 1.0.0"}

# v2
{:logpoint_api, "~> 2.0.0"}
```

The HTTP client changed from HTTPoison to Req, and Joken was added for
JWT-authenticated endpoints (alert rules, repos).

## Client setup

The plain credentials map is replaced by a `Client` struct built via the
facade.

```elixir
# v1
credentials = %{
  ip: "192.168.1.10",
  username: "admin",
  secret_key: "mysecret",
  verify_ssl: false
}

# v2
client = LogpointApi.client("https://192.168.1.10", "admin", "mysecret", ssl_verify: false)
```

Key differences:

- `ip` is now a full URL (`base_url`)
- `verify_ssl` is renamed to `ssl_verify`
- SSL verification defaults to `true` (was `false` in v1)

## Search

LogpointApi.Query is replaced by `LogpointApi.search_params/4,5`.
`run_search` is back with the same polling behaviour as v1 — see the
[Polling for Search Results](polling-search-results.md) guide for details.

```elixir
# v1
query = %LogpointApi.Query{
  query: "user=*",
  time_range: [1_714_986_600, 1_715_031_000],
  limit: 100,
  repos: ["127.0.0.1:5504"]
}
{:ok, result} = LogpointApi.run_search(credentials, query)

# v2
query = LogpointApi.search_params("user=*", 1_714_986_600, 1_715_031_000, 100, ["127.0.0.1:5504"])
{:ok, result} = LogpointApi.run_search(client, query)
```

Option names changed: `:poll_interval` → `:polling_interval`, `:max_retries` → `:max_attempts`.
The timeout error is now `{:error, :max_attempts_exceeded}` (atom instead of string).

| v1 | v2 |
|---|---|
| LogpointApi.run_search/2 | `LogpointApi.run_search/3` |
| LogpointApi.get_search_id/2 | `Search.get_id/2` |
| LogpointApi.get_search_result/2 | `Search.get_result/2` |
| LogpointApi.user_preference/1 | `Search.user_preference/1` |
| LogpointApi.logpoint_repos/1 | `Search.logpoint_repos/1` |
| LogpointApi.devices/1 | `Search.devices/1` |
| LogpointApi.livesearches/1 | `Search.livesearches/1` |

## Incidents

All incident functions moved to `LogpointApi.Core.Incident`.

```elixir
# v1
{:ok, incidents} = LogpointApi.incidents(credentials, start_time, end_time)
{:ok, _} = LogpointApi.resolve_incidents(credentials, ["id1"])
{:ok, _} = LogpointApi.add_comments(credentials, %{"id1" => ["note"]})

# v2
alias LogpointApi.Core.Incident

{:ok, incidents} = Incident.list(client, start_time, end_time)
{:ok, _} = Incident.resolve(client, ["id1"])

comment = LogpointApi.comment("id1", "note")
{:ok, _} = Incident.add_comments(client, [comment])
```

| v1 | v2 |
|---|---|
| LogpointApi.incidents/3 | `Incident.list/3` |
| LogpointApi.incident_states/3 | `Incident.list_states/3` |
| LogpointApi.incident/3 | `Incident.get/3` |
| LogpointApi.add_comments/2 | `Incident.add_comments/2` |
| LogpointApi.assign_incidents/3 | `Incident.assign/3` |
| LogpointApi.resolve_incidents/2 | `Incident.resolve/2` |
| LogpointApi.close_incidents/2 | `Incident.close/2` |
| LogpointApi.reopen_incidents/2 | `Incident.reopen/2` |
| LogpointApi.users/1 | `Incident.get_users/1` |

New in v2: `list/4` and `list_states/4` accept an optional filters map.

## Removed modules

| Removed | v2 replacement |
|---|---|
| LogpointApi.Query | `LogpointApi.search_params/4,5` |
| LogpointApi.Incident | `Incident.get/3` |
| LogpointApi.TimeRange | Inline args |
| LogpointApi.IncidentComment | `LogpointApi.comment/2` |
| LogpointApi.IncidentCommentData | Pass `[Comment.t()]` directly |
| LogpointApi.IncidentIDs | Pass `[String.t()]` directly |

## New in v2

These domains are entirely new and have no v1 equivalent:

- **Alert Rules** — `LogpointApi.Core.AlertRule` with builder pattern via `LogpointApi.rule/1`
- **Email Notifications** — builder via `LogpointApi.email_notification/2`
- **HTTP Notifications** — builder via `LogpointApi.http_notification/3`
- **Logpoint Repos** — `LogpointApi.Core.LogpointRepo`
- **User-Defined Lists** — `LogpointApi.Core.UserDefinedList`
- **Incident filtering** — optional filters map on `list/4` and `list_states/4`

See the `LogpointApi` module docs for full usage examples.
