typed_eav 0.1.0 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (40) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +80 -0
  3. data/README.md +634 -2
  4. data/app/models/typed_eav/field/base.rb +552 -6
  5. data/app/models/typed_eav/field/currency.rb +125 -0
  6. data/app/models/typed_eav/field/file.rb +98 -0
  7. data/app/models/typed_eav/field/image.rb +152 -0
  8. data/app/models/typed_eav/field/percentage.rb +100 -0
  9. data/app/models/typed_eav/field/reference.rb +230 -0
  10. data/app/models/typed_eav/section.rb +114 -4
  11. data/app/models/typed_eav/value.rb +461 -11
  12. data/app/models/typed_eav/value_version.rb +96 -0
  13. data/db/migrate/20260430000000_add_parent_scope_to_typed_eav_partitions.rb +188 -0
  14. data/db/migrate/20260501000000_add_cascade_policy_to_typed_eav_fields.rb +41 -0
  15. data/db/migrate/20260505000000_create_typed_eav_value_versions.rb +120 -0
  16. data/db/migrate/20260506000001_add_version_group_id_to_typed_eav_value_versions.rb +76 -0
  17. data/lib/generators/typed_eav/scaffold/templates/config/initializers/typed_eav.rb +7 -5
  18. data/lib/generators/typed_eav/scaffold/templates/controllers/typed_eav_controller.rb +72 -65
  19. data/lib/generators/typed_eav/scaffold/templates/views/typed_eav/forms/_common_fields.html.erb +13 -3
  20. data/lib/generators/typed_eav/scaffold/templates/views/typed_eav/index.html.erb +2 -0
  21. data/lib/generators/typed_eav/scaffold/templates/views/typed_eav/show.html.erb +3 -0
  22. data/lib/typed_eav/bulk_write.rb +147 -0
  23. data/lib/typed_eav/column_mapping.rb +46 -0
  24. data/lib/typed_eav/config.rb +215 -19
  25. data/lib/typed_eav/csv_mapper.rb +158 -0
  26. data/lib/typed_eav/currency_storage_contract.rb +46 -0
  27. data/lib/typed_eav/engine.rb +117 -0
  28. data/lib/typed_eav/event_dispatcher.rb +151 -0
  29. data/lib/typed_eav/field_storage_contract.rb +68 -0
  30. data/lib/typed_eav/has_typed_eav.rb +455 -58
  31. data/lib/typed_eav/partition.rb +64 -0
  32. data/lib/typed_eav/query_builder.rb +39 -3
  33. data/lib/typed_eav/registry.rb +48 -9
  34. data/lib/typed_eav/schema_portability.rb +250 -0
  35. data/lib/typed_eav/version.rb +1 -1
  36. data/lib/typed_eav/versioned.rb +73 -0
  37. data/lib/typed_eav/versioning/subscriber.rb +161 -0
  38. data/lib/typed_eav/versioning.rb +94 -0
  39. data/lib/typed_eav.rb +180 -12
  40. metadata +35 -1
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d634ac47d7ecea149ffb2d61e837db1a59d7a5dd37f9f4e820baca35a4e5e6c6
4
- data.tar.gz: 507b9bfe48fb62694230196c838cd683050f770d711412d0b56fab35e93cfb5c
3
+ metadata.gz: baca2cc8536abd74f256197ca9204cab2cd552a1935be48c87cb80fa914ac8e6
4
+ data.tar.gz: 3f61937a75ab864caa261359104cf4309fee8d8215b5603fbbd98f9be2c93f11
5
5
  SHA512:
6
- metadata.gz: 714f43c7d48e4592222298df3ba7065ee40efce7a6e31c49f1342aaa09ae7121082a48e4572035ff173562e077d723bbad5d9dd81a8da01305331ecc7d7ed795
7
- data.tar.gz: 54ee629ae6662faad51aa3357e194455bec33a3d30be5d2675b1d1ddfcc25e386b3d8e7a0cf6786bfb7bc0c2ce4de1b5a52e8444e12591ce7d3a5482cd4807d4
6
+ metadata.gz: ec9cfdb735c0820997082e991b07ed3d204bc362d40f0c85495a92b91320470c1ed89906d75a824573256f545d886df5a4ecf37ef4f866be33ccfc6e9d49c88e
7
+ data.tar.gz: 1c575620e89da9da387c02a92d891288a7cf9558c6296008afe38081ce65f5716c385e2ad4c7eb4caecf38b376bc3f61a1437c9c15d9754657b2c7f45f328741
data/CHANGELOG.md CHANGED
@@ -5,8 +5,88 @@ All notable changes to this project will be documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## [0.2.0] - 2026-04-29
9
+
10
+ Two-level scope partitioning. Field and section definitions now partition on
11
+ the tuple `(entity_type, scope, parent_scope)`, so an app can scope custom
12
+ fields per workspace inside a tenant (or any second axis your domain needs)
13
+ without giving up the existing single-scope ergonomics.
14
+
15
+ ### Added
16
+
17
+ - `parent_scope_method:` kwarg on `has_typed_eav` for two-level partition keys.
18
+ Requires `scope_method:` — declaring `parent_scope_method:` without it
19
+ raises at macro-expansion time.
20
+ - `parent_scope:` kwarg on `where_typed_eav`, `with_field`, and
21
+ `typed_eav_definitions` for explicit per-query overrides.
22
+ - `TypedEAV.with_scope` accepts a `[scope, parent_scope]` tuple form. The
23
+ scalar form `with_scope(value)` is preserved (treated as `[value, nil]`).
24
+ - `idx_te_sections_lookup` index for parity with `idx_te_fields_lookup`.
25
+
26
+ ### Changed
27
+
28
+ - **BREAKING** `Config.scope_resolver` callables MUST return a 2-element Array
29
+ `[scope, parent_scope]`. v0.1.x callables returning a bare scalar will raise
30
+ `ArgumentError` at the next ambient query — there is no silent fallback. If
31
+ you don't use parent_scope, return `[scope, nil]`.
32
+ - `TypedEAV.current_scope` now returns `[scope, parent_scope]` (or `nil`); was
33
+ a String/nil scalar.
34
+ - `Config::DEFAULT_SCOPE_RESOLVER` (the `acts_as_tenant` auto-detect) returns
35
+ `[ActsAsTenant.current_tenant, nil]`. The parent_scope slot is `nil`
36
+ because the tenant gem has no parent-scope analog.
37
+ - `Field::Base.for_entity` and `Section.for_entity` accept a `parent_scope:`
38
+ kwarg (defaults to `nil`).
39
+ - AR uniqueness validators on `Field` (on `:name`) and `Section` (on `:code`)
40
+ include `parent_scope` in their scope key.
41
+ - Three-way collision precedence in `definitions_by_name`: full-triple wins,
42
+ then scope-only, then global.
43
+ - Paired partial unique indexes now cover the new tuple. Old
44
+ `idx_te_fields_unique_scoped` / `idx_te_fields_unique_global` (and the
45
+ Section equivalents) are replaced by `_uniq_scoped_full` /
46
+ `_uniq_scoped_only` / `_uniq_global` per table.
47
+ - `idx_te_fields_lookup` recreated with `parent_scope` between `scope` and
48
+ `sort_order`.
49
+
50
+ ### Validation
51
+
52
+ - `Field::Base#validate_parent_scope_invariant` rejects rows where
53
+ `parent_scope.present?` and `scope.blank?` (no orphan-parent rows).
54
+ - `Section#validate_parent_scope_invariant` is the symmetric guard.
55
+ - `Value#validate_field_scope_matches_entity` extended to the parent_scope
56
+ axis: a `Value` whose host's `typed_eav_parent_scope` doesn't match the
57
+ field's `parent_scope` is rejected.
58
+
59
+ ### Migration steps
60
+
61
+ 1. Run `bin/rails typed_eav:install:migrations` to copy
62
+ `AddParentScopeToTypedEavPartitions` into your app.
63
+ 2. Run `bin/rails db:migrate`. The migration uses `CREATE INDEX CONCURRENTLY`
64
+ for all index changes and is safe on production tables — existing rows
65
+ are not rewritten.
66
+ 3. Update any custom `TypedEAV.config.scope_resolver` lambda to return
67
+ `[scope, parent_scope]`. If you don't use parent_scope, return
68
+ `[scope, nil]`. A bare scalar return surfaces as `ArgumentError` at
69
+ runtime — there is no silent fallback.
70
+ 4. Optional: declare `parent_scope_method:` on hosts that have an in-tenant
71
+ partition. Existing single-scope models continue to work without changes.
72
+
73
+ See the README ["Migrating from v0.1.x"](README.md#migrating-from-v01x)
74
+ section for the full guidance, including the orphan-parent invariant and
75
+ worked examples.
76
+
77
+ ### References
78
+
79
+ - `5ff7c30` — migration scaffolding (column + paired partials + lookup index).
80
+ - `52014a3` — resolver tuple contract on `with_scope` / `Config`.
81
+ - `6c3afb5` — `Field` partition tuple + orphan-parent guard.
82
+ - `9c7e916` — `Section` partition tuple + orphan-parent guard (symmetric).
83
+ - `c628372` — `parent_scope_method:` macro, query path wiring, `Value`
84
+ cross-axis guard.
85
+ - `e5e78a4` — spec coverage (440 examples, 0 failures).
86
+
8
87
  ## [0.1.0] - 2026-04-25
9
88
 
10
89
  Initial release.
11
90
 
91
+ [0.2.0]: https://github.com/dchuk/typed_eav/releases/tag/v0.2.0
12
92
  [0.1.0]: https://github.com/dchuk/typed_eav/releases/tag/v0.1.0