You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
The provider DSL declaration `characteristic :foo, SomeValueModule` currently assumes `SomeValueModule` is a plain struct used only to seed a `Diffo.Type.Value` dynamic stored on the generic `Diffo.Provider.Characteristic` resource. This means:
Characteristic values are opaque to Ash — no native filtering, sorting, or expression calculations on typed fields.
`TransformBehaviour` / `Extension.Characteristic` exist largely to work around the dynamic, creating and relating characteristics via custom wiring rather than standard Ash relationship management.
The assigner has to spelunk through `Diffo.Type.Value` internals to update individual fields, and the `parent()` / embedded resource approach to liveness doesn't work.
Proposed change
Introduce `Diffo.Provider.BaseCharacteristic` as an Ash Resource Fragment (parallel to `BaseInstance` / `BaseParty` / `BasePlace`). Characteristic type modules become Ash Resources that `use` `BaseCharacteristic`, gaining real typed Ash attributes and standard Ash relationship management.
What stays
`Diffo.Provider.Characteristic` (the existing generic concrete resource, using `Diffo.Type.Value`) is retained as-is. It may itself extend `BaseCharacteristic`, making it one valid option alongside typed resources. The DSL just won't force this approach — it accepts any `BaseCharacteristic`-derived resource, so the caller chooses typed, union, or dynamic depending on what the characteristic shape demands.
DSL impact
`characteristic :foo, SomeModule` continues to work syntactically. `SomeModule` must be a `BaseCharacteristic`-derived resource; `Diffo.Provider.Characteristic` remains available as the dynamic option. `VerifyCharacteristics` is updated to check `BaseCharacteristic` extension.
Instance behaviour simplification
With characteristics as proper resources, creating an instance's characteristics becomes standard `manage_relationship` on the Instance's create action. The custom `set_characteristics_argument` / `create_characteristics_from_declarations` wiring in `Extension.Characteristic` can be removed or simplified. `TransformBehaviour` and `ActionCreate` simplify accordingly.
Neo4j model
Each `BaseCharacteristic`-derived resource becomes a distinct Neo4j node label. `Diffo.Provider.Characteristic` continues to produce `:Characteristic` nodes for the dynamic case.
Acceptance criteria
`Diffo.Provider.BaseCharacteristic` fragment defined
`Diffo.Provider.Characteristic` extended from `BaseCharacteristic` (or compatible with it)
Typed characteristic modules (e.g. `ShelfValue`) migrated to extend `BaseCharacteristic`
`VerifyCharacteristics` updated to check `BaseCharacteristic` extension
`Extension.Characteristic` wiring simplified; replaced by standard relationship management where applicable
Assigner refactor (refactor assigner #120) — `AssignableValue` becomes a `BaseCharacteristic`-derived resource; fields, aggregates, and calculations live directly on it, removing all `Ash.Type.Dynamic` / `parent()` workarounds
Motivation
The provider DSL declaration `characteristic :foo, SomeValueModule` currently assumes `SomeValueModule` is a plain struct used only to seed a `Diffo.Type.Value` dynamic stored on the generic `Diffo.Provider.Characteristic` resource. This means:
Proposed change
Introduce `Diffo.Provider.BaseCharacteristic` as an Ash Resource Fragment (parallel to `BaseInstance` / `BaseParty` / `BasePlace`). Characteristic type modules become Ash Resources that `use` `BaseCharacteristic`, gaining real typed Ash attributes and standard Ash relationship management.
What stays
`Diffo.Provider.Characteristic` (the existing generic concrete resource, using `Diffo.Type.Value`) is retained as-is. It may itself extend `BaseCharacteristic`, making it one valid option alongside typed resources. The DSL just won't force this approach — it accepts any `BaseCharacteristic`-derived resource, so the caller chooses typed, union, or dynamic depending on what the characteristic shape demands.
DSL impact
`characteristic :foo, SomeModule` continues to work syntactically. `SomeModule` must be a `BaseCharacteristic`-derived resource; `Diffo.Provider.Characteristic` remains available as the dynamic option. `VerifyCharacteristics` is updated to check `BaseCharacteristic` extension.
Instance behaviour simplification
With characteristics as proper resources, creating an instance's characteristics becomes standard `manage_relationship` on the Instance's create action. The custom `set_characteristics_argument` / `create_characteristics_from_declarations` wiring in `Extension.Characteristic` can be removed or simplified. `TransformBehaviour` and `ActionCreate` simplify accordingly.
Neo4j model
Each `BaseCharacteristic`-derived resource becomes a distinct Neo4j node label. `Diffo.Provider.Characteristic` continues to produce `:Characteristic` nodes for the dynamic case.
Acceptance criteria
Sequencing