# `DpExchange.Core.Types.NewsItem`
[🔗](https://github.com/DistortionPoint/dp-exchange-core/blob/v0.3.120/lib/dp_exchange/core/types/news_item.ex#L1)

One news item, as the venue published it.

## The text is the venue's, and is not summarised here

`:summary` is whatever the venue supplied. This layer does not shorten, translate or
rewrite it: a normalisation that altered the text would change what a caller acted on
while leaving every field looking correct.

`:url` is the item's own address where the venue gives one. Following it is the caller's
decision and this package never does it.

## `:symbols` is what the venue tagged, not what the story is about

Tagging is the venue's, and venues tag differently — some by mention, some by relevance
model. A caller filtering by symbol is filtering by the venue's judgement, and that is
worth knowing before building an alert on it.

# `t`

```elixir
@type t() :: %DpExchange.Core.Types.NewsItem{
  headline: String.t() | nil,
  id: String.t(),
  provider: atom(),
  published_at: DateTime.t() | nil,
  source: String.t() | nil,
  summary: String.t() | nil,
  symbols: [String.t()] | nil,
  url: String.t() | nil
}
```

# `new`

```elixir
@spec new(keyword() | map()) :: t()
```

Builds a `t:t/0`, failing closed if a required field is absent or `nil`.

`@enforce_keys` guards presence, not `nil` — see `DpExchange.Core.Types.Validate`.

Also raises on a `:symbols` that is not a proper list of non-blank strings. `nil` is "the
venue did not tag this item" and `[]` is "tagged, and nothing"; the two stay apart.

---

*Consult [api-reference.md](api-reference.md) for complete listing*
