# `PhoenixKitProjects.Schemas.Task`
[🔗](https://github.com/BeamLabEU/phoenix_kit_projects/blob/v0.14.0/lib/phoenix_kit_projects/schemas/task.ex#L1)

Reusable task template with title, description, estimated duration,
and optional default assignee.

# `t`

```elixir
@type t() :: %PhoenixKitProjects.Schemas.Task{
  __meta__: term(),
  default_assigned_department:
    PhoenixKitStaff.Schemas.Department.t()
    | Ecto.Association.NotLoaded.t()
    | nil,
  default_assigned_department_uuid: UUIDv7.t() | nil,
  default_assigned_person:
    PhoenixKitStaff.Schemas.Person.t() | Ecto.Association.NotLoaded.t() | nil,
  default_assigned_person_uuid: UUIDv7.t() | nil,
  default_assigned_team:
    PhoenixKitStaff.Schemas.Team.t() | Ecto.Association.NotLoaded.t() | nil,
  default_assigned_team_uuid: UUIDv7.t() | nil,
  description: String.t() | nil,
  estimated_duration: integer() | nil,
  estimated_duration_unit: String.t() | nil,
  inserted_at: DateTime.t() | nil,
  position: integer() | nil,
  title: String.t() | nil,
  translations: translations_map(),
  updated_at: DateTime.t() | nil,
  uuid: UUIDv7.t() | nil
}
```

# `translations_map`

```elixir
@type translations_map() :: %{
  optional(String.t()) =&gt; %{optional(String.t()) =&gt; String.t()}
}
```

JSONB map of secondary-language overrides for translatable fields.
Same shape as `Project.translations_map` — primary stays in the
dedicated columns, this map only carries non-primary overrides.

# `changeset`

```elixir
@spec changeset(t(), map()) :: Ecto.Changeset.t()
```

# `duration_units`

```elixir
@spec duration_units() :: [String.t()]
```

# `format_duration`

```elixir
@spec format_duration(integer() | nil, String.t() | nil) :: String.t()
```

# `localized_description`

```elixir
@spec localized_description(t(), String.t() | nil) :: String.t() | nil
```

Same fallback semantics as `localized_title/2` — for `description`.

# `localized_title`

```elixir
@spec localized_title(t(), String.t() | nil) :: String.t() | nil
```

Returns the task's title in the requested language, falling back to
the primary `title` column when the language has no override (or the
override is empty/nil).

# `to_hours`

```elixir
@spec to_hours(number() | nil, String.t() | nil, boolean()) :: number()
```

Converts a duration to hours under a given calendar mode.

# `translatable_fields`

```elixir
@spec translatable_fields() :: [String.t()]
```

DB-column field names that participate in the `translations` JSONB.

---

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