# `PhoenixKit.Migrations.Postgres.V122`
[🔗](https://github.com/BeamLabEU/phoenix_kit/blob/v1.7.165/lib/phoenix_kit/migrations/postgres/v122.ex#L1)

V122: Three unrelated additions bundled together because they shipped
in the same release cycle.

## 1. `phoenix_kit_location_spaces` — nested floors / rooms / zones
under a `phoenix_kit_locations` row

Each row belongs to exactly one Location (required FK, cascade) and
may optionally belong to a parent Space within the same Location
(self-ref FK, cascade) forming a filesystem-like tree of arbitrary
depth.

The cross-row "child belongs to same location as parent" guarantee
is enforced at application layer in `PhoenixKitLocations.Spaces` —
enforcing it at the DB requires a composite FK + redundant column
pair which is heavier than the consumer surface justifies.

`data JSONB` mirrors the parent Location's column: top-level keys
carry attachment pointers (`files_folder_uuid`, `featured_image_uuid`)
and the multilang translation tree (`%{ "es-ES" => %{ "name" =>
"..."} }`). Primary-language values stay denormalized in the
dedicated `name` / `description` columns for cheap querying.

## 2. `translations JSONB` on the three staff tables

Adds `translations JSONB NOT NULL DEFAULT '{}'` to
`phoenix_kit_staff_departments`, `phoenix_kit_staff_teams`, and
`phoenix_kit_staff_people`. Mirrors the settings-translations shape
already used by `phoenix_kit_projects` V112 (project / project_task /
project_assignment): primary stays in dedicated columns, the JSONB
holds non-primary overrides only.

    %{"es-ES" => %{"name" => "...", "description" => "..."}}

Translatable fields by schema:

  * Department: `name`, `description`
  * Team: `name`, `description`
  * Person: `job_title`, `bio`, `skills`, `notes`

Read paths use `<Schema>.localized_<field>/2` helpers with primary-
fallback semantics.

## 3. `name` column on `phoenix_kit_staff_people`

Adds a single nullable `name VARCHAR` for the staff person's full
display name — consistent with Department, Team, Space, and Location
which all use a single `name` field. Owned by the staff profile
rather than `phoenix_kit_users` because placeholder users created via
`Staff.find_or_create_user_by_email/1` are anonymous until claimed.

# `down`

# `up`

---

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