Join between Person and Skill — a person's assignment of a skill,
carrying zero or more of the skill's own proficiency levels.
proficiency_levels is a list of level ids referencing the parent
Skill.levels. [] means "no level / not set". A single-select skill
holds 0–1 ids; a multi-select skill holds 0–N.
Write path invariant: semantic validation of the ids (they must exist
in the parent skill's levels, and there must be ≤1 when the skill is
single-select) lives in PhoenixKitStaff.Skills, which is the sole
supported write path for assignments. This changeset only does structural
normalisation (reject blanks, dedup) — do not insert a PersonSkill
directly bypassing the context, or invalid/over-count ids can be persisted.
Summary
Types
@type t() :: %PhoenixKitStaff.Schemas.PersonSkill{ __meta__: term(), inserted_at: DateTime.t() | nil, proficiency_levels: [String.t()], skill: PhoenixKitStaff.Schemas.Skill.t() | Ecto.Association.NotLoaded.t() | nil, skill_uuid: UUIDv7.t() | nil, staff_person: PhoenixKitStaff.Schemas.Person.t() | Ecto.Association.NotLoaded.t() | nil, staff_person_uuid: UUIDv7.t() | nil, uuid: UUIDv7.t() | nil }
Functions
@spec changeset(t() | Ecto.Changeset.t(t()), map()) :: Ecto.Changeset.t(t())