Skip to content

Add metadata support for incidents, schedules and components#385

Open
jbrooksuk wants to merge 3 commits into
mainfrom
claude/metadata-support-filament-0swzoc
Open

Add metadata support for incidents, schedules and components#385
jbrooksuk wants to merge 3 commits into
mainfrom
claude/metadata-support-filament-0swzoc

Conversation

@jbrooksuk

Copy link
Copy Markdown
Member

Introduce a shared, filterable metadata capability, backed by the existing
polymorphic meta table, for incidents, schedules, components, component
groups and subscribers.

  • Add a Meta model and a HasMeta concern (with a Metable contract)
    exposing a meta() morph relation, metaValues() and syncMeta(). Values
    are cast to JSON so they retain their original type when read back.
  • Register the metadata-aware models in the morph map and migrate the existing
    components.meta JSON column into the polymorphic meta table, then drop
    the column. The meta.value column is widened to nullable text.
  • Persist metadata from the Filament resources via a KeyValue field and a
    shared page concern.
  • Accept meta on the create/update request data and sync it in the actions.
  • Expose meta as an optional API include (?include=meta) that renders the
    metadata as a key/value object, rather than always loading it.
  • Add a reusable MetaFilter so the API endpoints can filter by metadata
    (e.g. ?filter[meta][region]=eu-west).
  • Document the metadata filter and include on the relevant API endpoints.

Co-Authored-By: Claude Opus 4.8 noreply@anthropic.com
Claude-Session: https://claude.ai/code/session_01SjXufhWofngDAxRAgsxzyN

claude added 3 commits July 11, 2026 13:44
Introduce a shared, filterable metadata capability, backed by the existing
polymorphic `meta` table, for incidents, schedules, components, component
groups and subscribers.

- Add a `Meta` model and a `HasMeta` concern (with a `Metable` contract)
  exposing a `meta()` morph relation, `metaValues()` and `syncMeta()`. Values
  are cast to JSON so they retain their original type when read back.
- Register the metadata-aware models in the morph map and migrate the existing
  `components.meta` JSON column into the polymorphic `meta` table, then drop
  the column. The `meta.value` column is widened to nullable text.
- Persist metadata from the Filament resources via a `KeyValue` field and a
  shared page concern.
- Accept `meta` on the create/update request data and sync it in the actions.
- Expose `meta` as an optional API include (`?include=meta`) that renders the
  metadata as a key/value object, rather than always loading it.
- Add a reusable `MetaFilter` so the API endpoints can filter by metadata
  (e.g. `?filter[meta][region]=eu-west`).
- Document the metadata filter and include on the relevant API endpoints.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SjXufhWofngDAxRAgsxzyN
Address the highest-severity review findings on the metadata feature:

- `MetaFilter` now matches typed metadata values: query-string input is
  compared against every plausible JSON encoding (string, integer, float and
  boolean), so `?filter[meta][priority]=3` matches an integer 3 as well as
  the string "3". Boolean values already converted by the query builder are
  handled too.
- `HasMeta` purges a model's metadata when it is hard or force deleted
  (soft-deleted models keep their metadata for restores), and the demo
  seeder truncates the `meta` table, so orphaned rows can no longer attach
  to unrelated records that reuse an id.
- `syncMeta()` casts keys to strings before pruning, avoiding MySQL's
  numeric coercion matching every key against integer array keys.
- The component meta migration logs a warning instead of silently skipping
  payloads that do not decode to an array, batch-inserts each component's
  rows, hardcodes the morph aliases so the frozen migration no longer
  depends on the runtime morph map, and `down()` now restores the original
  `meta.value` string column definition after removing the rows this
  feature wrote.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SjXufhWofngDAxRAgsxzyN
PHPStan analyses the HasMeta trait once per consuming model, so the
method_exists() probe for isForceDeleting() was reported as always-true on
soft-deleting models. Checking $model->exists expresses the same rule
directly: soft-deleted models still exist and keep their metadata, while
hard and force deleted models are gone and have their metadata purged.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SjXufhWofngDAxRAgsxzyN
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants