PhoenixKit.Annotations.Annotation (phoenix_kit v2.16.0)

Copy Markdown View Source

Ecto schema for phoenix_kit_annotations.

Stores user-drawn shapes (rectangle, circle, polygon, freehand) tied to a target: target_type + target_uuid, Etcher's own vocabulary. A "file" target is a PhoenixKit.Modules.Storage.File and carries its uuid in file_uuid as well (the hard FK every file-side feature — the thumbnail job, has_annotations?/1, the comment threads — keys on). Any other target (a projects whiteboard, say) carries NO file: the shapes sit on an empty Fresco canvas. V183 pins the two shapes with a CHECK. All geometry is in canvas-pixel coordinates; Fresco's coordinate adapter rescales for pan/zoom at render time.

Comment thread linkage

An annotation's discussion lives in phoenix_kit_comments anchored to the file (resource_type = "file", resource_uuid = file_uuid) with metadata.annotation_uuid carrying the back-reference. This lets annotation-rooted comments appear in the file's main comments thread alongside non-annotated discussion. There is no comment_uuid column on annotations — the relationship is one-directional from the comment side, and a thread is created lazily when the first comment is posted.

Summary

Functions

Fields the Etcher storage adapter is allowed to take from event payloads. Single source of truth so the adapter's whitelist doesn't drift from the schema's @cast_fields. The target columns are excluded — the adapter sets them server-side from the Etcher target_type / target_uuid, never from the payload.

List of allowed kind strings.

Shape a target_type must have.

Types

t()

@type t() :: %PhoenixKit.Annotations.Annotation{
  __meta__: term(),
  creator_uuid: UUIDv7.t() | nil,
  file_uuid: UUIDv7.t() | nil,
  geometry: map(),
  inserted_at: DateTime.t() | nil,
  kind: String.t(),
  metadata: map() | nil,
  position: integer(),
  style: map() | nil,
  target_type: String.t(),
  target_uuid: UUIDv7.t() | nil,
  title: String.t() | nil,
  updated_at: DateTime.t() | nil,
  uuid: UUIDv7.t() | nil
}

Functions

adapter_writable_fields()

@spec adapter_writable_fields() :: [atom()]

Fields the Etcher storage adapter is allowed to take from event payloads. Single source of truth so the adapter's whitelist doesn't drift from the schema's @cast_fields. The target columns are excluded — the adapter sets them server-side from the Etcher target_type / target_uuid, never from the payload.

kinds()

List of allowed kind strings.

target_type_format()

@spec target_type_format() :: Regex.t()

Shape a target_type must have.

Shared with the Etcher adapter, which rejects a malformed target before building attrs at all (the protocol wants {:error, :unsupported_target}, not a changeset). One regex so the two answers cannot disagree.