These docs are a work in progress and may not be fully up to date. Some pages may contain internal notes for our team.
Skip to Content

Data model — Tag

A Tag is a workspace-scoped free-form label that can be applied to Locations and surfaced as a refinement option in the Finder widget.

Table: tags

ColumnTypeNullableDescription
idbigint (auto-increment)noPrimary key
namevarchar (unique at creation)noHuman-readable label shown in the widget
slugvarchar (unique at creation)noURL/SEO-safe identifier; used as the refinement value
descriptiontextyesOptional internal description
workspace_idbigint (FK → workspaces.id)yesOwning workspace; set to null on workspace deletion (nullOnDelete). Added in migration 2026_04_05
created_attimestampnoLaravel auto-managed
updated_attimestampnoLaravel auto-managed

⚠️ Warning: The original tags migration created name and slug with a database-level unique() constraint. The workspace_id column was added later. If workspace_id is null the tag has no workspace affiliation — this is a legacy state from before the workspace-scoped migration. New tags always have a workspace_id.

Relations

  • belongsTo Workspace — direct foreign key workspace_id. A Tag belongs to exactly one Workspace.
  • belongsToMany Location — via location_tag pivot. The locations that have this tag applied.

Slug

The slug field is the stable identifier for the Tag in refinement rules and URL params. Slug generation is handled on the frontend or at the API layer before persisting. 🔴 [NEEDS CLARIFICATION: Is the slug auto-generated from name on the backend, or is it a required field the caller must supply?]

Tags are referenced by slug in refinement configuration — if a tag is renamed its slug should remain stable to avoid breaking active refinement rules.

Workspace scoping

Tags are scoped to a single workspace via workspace_id. The migration 2026_04_05_000003_add_workspace_id_to_tags_table.php back-filled workspace_id for all existing tags by joining through location_taglocation_workspace. Tags that could not be matched to a workspace were assigned the lowest-id workspace as a fallback.

Computed / virtual attributes

None. No $appends, no JSON casts.