# `OCSF.Event`
[🔗](https://github.com/docjerem/ocsf/blob/v0.1.0/lib/ocsf/event.ex#L1)

OCSF event struct.

Represents a single OCSF-compliant security event. Mirrors the
[OCSF 1.8 base event](https://schema.ocsf.io/1.8.0/base_event) with
nested object structs for `metadata`, `user`, `http_request`, etc.

Use per-class builders (`OCSF.Events.Authentication`) rather than
`new/1` directly. The low-level constructor is public for replay
tooling and deserialization.

## Fields

- `:metadata` — `%OCSF.Metadata{}` (required). Carries `uid`,
  `version`, `product`, `event_code`, `correlation_uid`.
- `:time` — `DateTime.t()` (required). UTC event timestamp.
- `:category_uid` — integer. Top-level OCSF category.
- `:class_uid` — integer. OCSF event class.
- `:type_uid` — integer. `class_uid * 100 + activity_id`.
- `:activity_id` — integer. Class-scoped activity.
- `:severity_id` — integer. Severity level.
- `:status_id` — integer. Event status.
- `:status_detail` — `String.t() | nil`. Free-form detail.
- `:auth_protocol_id` — `integer | nil`. Auth protocol.
- `:user` — `%OCSF.User{} | nil`.
- `:actor` — `%OCSF.Actor{} | nil`.
- `:http_request` — `%OCSF.HttpRequest{} | nil`.
- `:src_endpoint` — `%OCSF.NetworkEndpoint{} | nil`.
- `:dst_endpoint` — `%OCSF.NetworkEndpoint{} | nil`.
- `:service` — `%OCSF.Service{} | nil`.
- `:raw_data` — `String.t() | nil`. Raw event payload.
- `:unmapped` — `map | nil`. Extension escape hatch.

See `OCSF.validate/1`, `OCSF.to_map/1`, `OCSF.Events.Authentication`.

# `t`

```elixir
@type t() :: %OCSF.Event{
  activity_id: integer(),
  actor: OCSF.Actor.t() | nil,
  auth_protocol_id: integer() | nil,
  category_uid: integer(),
  class_uid: integer(),
  dst_endpoint: OCSF.NetworkEndpoint.t() | nil,
  http_request: OCSF.HttpRequest.t() | nil,
  metadata: OCSF.Metadata.t(),
  raw_data: String.t() | nil,
  service: OCSF.Service.t() | nil,
  severity_id: integer(),
  src_endpoint: OCSF.NetworkEndpoint.t() | nil,
  status_detail: String.t() | nil,
  status_id: integer(),
  time: DateTime.t(),
  type_uid: integer(),
  unmapped: map() | nil,
  user: OCSF.User.t() | nil
}
```

# `from_map`

```elixir
@spec from_map(map()) :: {:ok, t()} | {:error, OCSF.Error.t()}
```

Reconstruct an event from a nested OCSF map.

Accepts the map shape produced by `OCSF.to_map/1`. Runs validation
after construction. Provides the round-trip guarantee:
`event |> OCSF.to_map() |> OCSF.Event.from_map()` returns
`{:ok, ^event}` (modulo nil-omitted fields).

Delegates to `OCSF.Deserializer.from_map/1`.

# `new`

```elixir
@spec new(keyword() | map()) :: {:ok, t()} | {:error, OCSF.Error.t()}
```

Build an event from a keyword list or map.

This is the low-level constructor. Prefer per-class builders
(`OCSF.Events.Authentication.logon/1`) which auto-resolve class,
category, type, and activity fields.

Casts plain maps to their OCSF struct equivalents for nested objects.
Does NOT run validation — call `OCSF.validate/1` on the result.

## Examples

    iex> {:ok, event} = OCSF.Event.new(
    ...>   metadata: %OCSF.Metadata{
    ...>     uid: "test-uid",
    ...>     version: "1.8.0",
    ...>     product: %OCSF.Product{name: "Test"}
    ...>   },
    ...>   time: ~U[2026-04-15 10:00:00Z],
    ...>   category_uid: 3,
    ...>   class_uid: 3002,
    ...>   type_uid: 300201,
    ...>   activity_id: 1,
    ...>   severity_id: 1,
    ...>   status_id: 1
    ...> )
    iex> event.class_uid
    3002

---

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