hecks 0.2.0 → 0.3.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.
- checksums.yaml +5 -5
- data/lib/hecks/adapters/driven/claude_code.adapter +3 -0
- data/lib/hecks/adapters/driven/claude_code.rb +127 -0
- data/lib/hecks/adapters/driven/d1.adapter +12 -0
- data/lib/hecks/adapters/driven/d1.rb +403 -0
- data/lib/hecks/adapters/driven/folder.adapter +3 -0
- data/lib/hecks/adapters/driven/folder.rb +199 -0
- data/lib/hecks/adapters/driven/google_authentication.adapter +3 -0
- data/lib/hecks/adapters/driven/google_authentication.rb +100 -0
- data/lib/hecks/adapters/driven/governance_authorization.adapter +3 -0
- data/lib/hecks/adapters/driven/governance_authorization.rb +62 -0
- data/lib/hecks/adapters/driven/heki/journal.rb +51 -0
- data/lib/hecks/adapters/driven/heki/saga_store.rb +0 -0
- data/lib/hecks/adapters/driven/heki/snapshot.rb +38 -0
- data/lib/hecks/adapters/driven/heki.adapter +4 -0
- data/lib/hecks/adapters/driven/heki.rb +148 -0
- data/lib/hecks/adapters/driven/identity_registry.adapter +3 -0
- data/lib/hecks/adapters/driven/identity_registry.rb +26 -0
- data/lib/hecks/adapters/driven/in_memory_ordering.rb +51 -0
- data/lib/hecks/adapters/driven/lambda/client.rb +63 -0
- data/lib/hecks/adapters/driven/lambda.adapter +4 -0
- data/lib/hecks/adapters/driven/lambda.rb +131 -0
- data/lib/hecks/adapters/driven/memory.adapter +3 -0
- data/lib/hecks/adapters/driven/memory.rb +103 -0
- data/lib/hecks/adapters/driven/mock_stripe_adapter.adapter +3 -0
- data/lib/hecks/adapters/driven/mock_stripe_adapter.rb +28 -0
- data/lib/hecks/adapters/driven/postgres/codec.rb +80 -0
- data/lib/hecks/adapters/driven/postgres/schema_builder.rb +168 -0
- data/lib/hecks/adapters/driven/postgres.adapter +5 -0
- data/lib/hecks/adapters/driven/postgres.rb +391 -0
- data/lib/hecks/adapters/driven/postgres_era/lineage/era_store.rb +171 -0
- data/lib/hecks/adapters/driven/postgres_era/lineage/field_cache.rb +190 -0
- data/lib/hecks/adapters/driven/postgres_era/lineage/head_compiler.rb +429 -0
- data/lib/hecks/adapters/driven/postgres_era/lineage/mint_transaction.rb +166 -0
- data/lib/hecks/adapters/driven/postgres_era/lineage/provisioning.rb +286 -0
- data/lib/hecks/adapters/driven/postgres_era/lineage/resumable_backfill.rb +168 -0
- data/lib/hecks/adapters/driven/postgres_era/lineage/tail_merge.rb +163 -0
- data/lib/hecks/adapters/driven/postgres_era/lineage/transform_installer.rb +114 -0
- data/lib/hecks/adapters/driven/postgres_era/lineage.rb +137 -0
- data/lib/hecks/adapters/driven/postgres_era/lineage_manager/coverage_check.rb +89 -0
- data/lib/hecks/adapters/driven/postgres_era/lineage_manager/era_resolver.rb +82 -0
- data/lib/hecks/adapters/driven/postgres_era/lineage_manager/merge_coordinator.rb +43 -0
- data/lib/hecks/adapters/driven/postgres_era/lineage_manager/minter.rb +132 -0
- data/lib/hecks/adapters/driven/postgres_era/lineage_manager.rb +74 -0
- data/lib/hecks/adapters/driven/postgres_era.adapter +6 -0
- data/lib/hecks/adapters/driven/postgres_era.rb +671 -0
- data/lib/hecks/adapters/driven/prism.adapter +3 -0
- data/lib/hecks/adapters/driven/prism.rb +80 -0
- data/lib/hecks/adapters/driven/secure_random_identity.adapter +3 -0
- data/lib/hecks/adapters/driven/secure_random_identity.rb +14 -0
- data/lib/hecks/adapters/driven/sql_query_builder.rb +221 -0
- data/lib/hecks/adapters/driven/sqlite/codec.rb +63 -0
- data/lib/hecks/adapters/driven/sqlite/projection.rb +105 -0
- data/lib/hecks/adapters/driven/sqlite/schema_builder.rb +180 -0
- data/lib/hecks/adapters/driven/sqlite.adapter +9 -0
- data/lib/hecks/adapters/driven/sqlite.rb +285 -0
- data/lib/hecks/adapters/driven/system_clock.adapter +3 -0
- data/lib/hecks/adapters/driven/system_clock.rb +14 -0
- data/lib/hecks/adapters/driven.rb +36 -0
- data/lib/hecks/adapters.rb +6 -0
- data/lib/hecks/behaviors/dsl.rb +96 -0
- data/lib/hecks/behaviors/expectations.rb +280 -0
- data/lib/hecks/behaviors/ir.rb +31 -0
- data/lib/hecks/behaviors/rspec.rb +42 -0
- data/lib/hecks/behaviors/runner.rb +96 -0
- data/lib/hecks/behaviors.rb +25 -0
- data/lib/hecks/bluebook/aggregate.rb +108 -0
- data/lib/hecks/bluebook/assembly/aggregate_assembly.rb +134 -0
- data/lib/hecks/bluebook/assembly/build.rb +48 -0
- data/lib/hecks/bluebook/assembly/contract.rb +112 -0
- data/lib/hecks/bluebook/assembly/contracts.rb +409 -0
- data/lib/hecks/bluebook/assembly/marks.rb +227 -0
- data/lib/hecks/bluebook/assembly/specializer.rb +70 -0
- data/lib/hecks/bluebook/assembly.rb +78 -0
- data/lib/hecks/bluebook/attribute.rb +96 -0
- data/lib/hecks/bluebook/behaviour/aggregate.rb +83 -0
- data/lib/hecks/bluebook/behaviour/attribute.rb +27 -0
- data/lib/hecks/bluebook/behaviour/chapter.rb +72 -0
- data/lib/hecks/bluebook/behaviour/command.rb +116 -0
- data/lib/hecks/bluebook/behaviour/domain_port.rb +25 -0
- data/lib/hecks/bluebook/behaviour/entity.rb +59 -0
- data/lib/hecks/bluebook/behaviour/hexagon.rb +50 -0
- data/lib/hecks/bluebook/behaviour/lifecycle.rb +51 -0
- data/lib/hecks/bluebook/behaviour/policy.rb +52 -0
- data/lib/hecks/bluebook/behaviour/process_manager.rb +38 -0
- data/lib/hecks/bluebook/behaviour/query.rb +10 -0
- data/lib/hecks/bluebook/behaviour/read_model.rb +29 -0
- data/lib/hecks/bluebook/behaviour/traits.rb +81 -0
- data/lib/hecks/bluebook/behaviour/value_object.rb +33 -0
- data/lib/hecks/bluebook/chapter.rb +68 -0
- data/lib/hecks/bluebook/command.rb +124 -0
- data/lib/hecks/bluebook/domain_port.rb +102 -0
- data/lib/hecks/bluebook/dsl/adapter_builder.rb +34 -0
- data/lib/hecks/bluebook/dsl/aggregate_builder.rb +906 -0
- data/lib/hecks/bluebook/dsl/attribute_collector.rb +327 -0
- data/lib/hecks/bluebook/dsl/binding_proxy.rb +71 -0
- data/lib/hecks/bluebook/dsl/bluebook_builder.rb +1018 -0
- data/lib/hecks/bluebook/dsl/command_builder.rb +626 -0
- data/lib/hecks/bluebook/dsl/const_shim.rb +81 -0
- data/lib/hecks/bluebook/dsl/domain_port_builder.rb +79 -0
- data/lib/hecks/bluebook/dsl/entity_builder.rb +305 -0
- data/lib/hecks/bluebook/dsl/generic_dispatch.rb +366 -0
- data/lib/hecks/bluebook/dsl/hecksagon_builder.rb +163 -0
- data/lib/hecks/bluebook/dsl/identity_declaration.rb +191 -0
- data/lib/hecks/bluebook/dsl/lifecycle_builder.rb +44 -0
- data/lib/hecks/bluebook/dsl/malformed.rb +7 -0
- data/lib/hecks/bluebook/dsl/policy_builder.rb +120 -0
- data/lib/hecks/bluebook/dsl/port_builder.rb +30 -0
- data/lib/hecks/bluebook/dsl/port_operation_builder.rb +142 -0
- data/lib/hecks/bluebook/dsl/process_manager_builder.rb +207 -0
- data/lib/hecks/bluebook/dsl/query_builder.rb +113 -0
- data/lib/hecks/bluebook/dsl/read_model_builder.rb +233 -0
- data/lib/hecks/bluebook/dsl/rule_reference.rb +172 -0
- data/lib/hecks/bluebook/dsl/translation_builder.rb +243 -0
- data/lib/hecks/bluebook/dsl/value_object_builder.rb +178 -0
- data/lib/hecks/bluebook/dsl/word_gate.rb +221 -0
- data/lib/hecks/bluebook/dsl/world_builder.rb +77 -0
- data/lib/hecks/bluebook/dsl.rb +45 -0
- data/lib/hecks/bluebook/entity.rb +103 -0
- data/lib/hecks/bluebook/expression/canonical_form.rb +55 -0
- data/lib/hecks/bluebook/expression/evaluator.rb +261 -0
- data/lib/hecks/bluebook/expression/projection.json +170 -0
- data/lib/hecks/bluebook/expression/resolver/block_predicates.rb +233 -0
- data/lib/hecks/bluebook/expression/resolver.rb +630 -0
- data/lib/hecks/bluebook/expression.rb +13 -0
- data/lib/hecks/bluebook/hexagon.rb +60 -0
- data/lib/hecks/bluebook/lifecycle.rb +42 -0
- data/lib/hecks/bluebook/meta_validator/adapter_judge.rb +54 -0
- data/lib/hecks/bluebook/meta_validator/judge.rb +559 -0
- data/lib/hecks/bluebook/meta_validator/plan.rb +332 -0
- data/lib/hecks/bluebook/meta_validator/port_judge.rb +47 -0
- data/lib/hecks/bluebook/meta_validator/readings.rb +350 -0
- data/lib/hecks/bluebook/meta_validator/reconstruction.rb +312 -0
- data/lib/hecks/bluebook/meta_validator/shapes.rb +246 -0
- data/lib/hecks/bluebook/meta_validator/syntax_boot.rb +255 -0
- data/lib/hecks/bluebook/meta_validator/translation_judge.rb +138 -0
- data/lib/hecks/bluebook/meta_validator/world_judge.rb +78 -0
- data/lib/hecks/bluebook/meta_validator.rb +452 -0
- data/lib/hecks/bluebook/model_check.rb +318 -0
- data/lib/hecks/bluebook/pattern_subset.rb +120 -0
- data/lib/hecks/bluebook/policy.rb +41 -0
- data/lib/hecks/bluebook/process_manager.rb +86 -0
- data/lib/hecks/bluebook/project_discovery.rb +30 -0
- data/lib/hecks/bluebook/project_loader.rb +40 -0
- data/lib/hecks/bluebook/project_register.rb +82 -0
- data/lib/hecks/bluebook/query.rb +61 -0
- data/lib/hecks/bluebook/read_model.rb +109 -0
- data/lib/hecks/bluebook/reference.rb +74 -0
- data/lib/hecks/bluebook/smoke_test.rb +166 -0
- data/lib/hecks/bluebook/synthesizer.rb +95 -0
- data/lib/hecks/bluebook/translation.rb +92 -0
- data/lib/hecks/bluebook/value_object.rb +58 -0
- data/lib/hecks/bluebook.rb +74 -0
- data/lib/hecks/codemod.rb +342 -0
- data/lib/hecks/construct.rb +71 -0
- data/lib/hecks/deploy/bluebook/deploy.bluebook +219 -0
- data/lib/hecks/deploy/bluebook/deploy.hecksagon +4 -0
- data/lib/hecks/deploy/oidc.json +18 -0
- data/lib/hecks/doc/reference.rb +389 -0
- data/lib/hecks/embryonaut_bluebook.rb +75 -0
- data/lib/hecks/facade/cli_door.rb +116 -0
- data/lib/hecks/facade/cli_runner.rb +190 -0
- data/lib/hecks/facade/command_request.rb +105 -0
- data/lib/hecks/facade/handle.rb +173 -0
- data/lib/hecks/facade/json_door.rb +154 -0
- data/lib/hecks/facade/surface/aggregate_door.rb +185 -0
- data/lib/hecks/facade/surface/chapter.rb +107 -0
- data/lib/hecks/facade/surface.rb +48 -0
- data/lib/hecks/facade.rb +44 -0
- data/lib/hecks/forms/app.rb +300 -0
- data/lib/hecks/forms/command_form_renderer.rb +113 -0
- data/lib/hecks/forms/examples/banking_console.bluebook +3 -0
- data/lib/hecks/forms/field_renderer.rb +170 -0
- data/lib/hecks/forms/field_shape.rb +232 -0
- data/lib/hecks/forms/html.rb +53 -0
- data/lib/hecks/forms/index_renderer.rb +35 -0
- data/lib/hecks/forms/page.rb +157 -0
- data/lib/hecks/forms/params.rb +132 -0
- data/lib/hecks/forms/query_form_renderer.rb +114 -0
- data/lib/hecks/forms/record_renderer.rb +115 -0
- data/lib/hecks/forms/record_table.rb +63 -0
- data/lib/hecks/forms/reference_options.rb +30 -0
- data/lib/hecks/forms/value_object_shape.rb +46 -0
- data/lib/hecks/forms.rb +54 -0
- data/lib/hecks/fqn.rb +94 -0
- data/lib/hecks/framework/bluebook/compliance.bluebook +1 -0
- data/lib/hecks/framework/bluebook/console_settings.bluebook +489 -0
- data/lib/hecks/framework/bluebook/framework.hecksagon +32 -0
- data/lib/hecks/framework/bluebook/governance.bluebook +130 -0
- data/lib/hecks/framework/bluebook/identity.bluebook +90 -0
- data/lib/hecks/framework/oidc.json +39 -0
- data/lib/hecks/framework.rb +90 -0
- data/lib/hecks/freezer.rb +67 -0
- data/lib/hecks/fuzzing/invalid_value_generator.rb +86 -0
- data/lib/hecks/fuzzing/isolated_boot.rb +92 -0
- data/lib/hecks/fuzzing/properties.rb +1146 -0
- data/lib/hecks/fuzzing/replay.rb +635 -0
- data/lib/hecks/fuzzing/sequence_generator/catalog.rb +93 -0
- data/lib/hecks/fuzzing/sequence_generator/outcome_tracker.rb +54 -0
- data/lib/hecks/fuzzing/sequence_generator/picker.rb +96 -0
- data/lib/hecks/fuzzing/sequence_generator/step_builder.rb +185 -0
- data/lib/hecks/fuzzing/sequence_generator.rb +130 -0
- data/lib/hecks/fuzzing/value_generator.rb +177 -0
- data/lib/hecks/fuzzing.rb +12 -0
- data/lib/hecks/grammar/evolve.rb +291 -0
- data/lib/hecks/grammar/expression.bluebook +417 -0
- data/lib/hecks/grammar/expression_operators.json +1152 -0
- data/lib/hecks/grammar/grammar.hecksagon +20 -0
- data/lib/hecks/grammar/oidc.json +69 -0
- data/lib/hecks/grammar/translation.bluebook +203 -0
- data/lib/hecks/grammar.rb +178 -0
- data/lib/hecks/ir.rb +126 -0
- data/lib/hecks/language/adapter.bluebook +116 -0
- data/lib/hecks/language/bluebook/aggregate.bluebook +581 -0
- data/lib/hecks/language/bluebook/attaches/paging.bluebook +76 -0
- data/lib/hecks/language/bluebook/bluebook.bluebook +256 -0
- data/lib/hecks/language/bluebook/bluebook.hecksagon +24 -0
- data/lib/hecks/language/bluebook/command.bluebook +437 -0
- data/lib/hecks/language/bluebook/entity.bluebook +316 -0
- data/lib/hecks/language/bluebook/policy.bluebook +172 -0
- data/lib/hecks/language/bluebook/process_manager.bluebook +264 -0
- data/lib/hecks/language/bluebook/projection.bluebook +267 -0
- data/lib/hecks/language/bluebook/query.bluebook +245 -0
- data/lib/hecks/language/bluebook/shape.bluebook +292 -0
- data/lib/hecks/language/bluebook/syntax.bluebook +447 -0
- data/lib/hecks/language/bluebook/vocabulary.bluebook +364 -0
- data/lib/hecks/language/hecksagon/adapter_binding.bluebook +51 -0
- data/lib/hecks/language/hecksagon/domain_port.bluebook +76 -0
- data/lib/hecks/language/hecksagon/hecksagon.bluebook +131 -0
- data/lib/hecks/language/hecksagon/port_operation.bluebook +102 -0
- data/lib/hecks/language/oidc.json +313 -0
- data/lib/hecks/language/port.bluebook +92 -0
- data/lib/hecks/language/translation/translation.bluebook +110 -0
- data/lib/hecks/language/translation/translation_aggregate.bluebook +267 -0
- data/lib/hecks/language/world/wiring.bluebook +62 -0
- data/lib/hecks/language/world/world.bluebook +84 -0
- data/lib/hecks/literal.rb +125 -0
- data/lib/hecks/naming.rb +121 -0
- data/lib/hecks/ports/access_control.port +4 -0
- data/lib/hecks/ports/access_control.rb +62 -0
- data/lib/hecks/ports/agent/answers.rb +104 -0
- data/lib/hecks/ports/agent.port +4 -0
- data/lib/hecks/ports/agent.rb +167 -0
- data/lib/hecks/ports/authentication.port +4 -0
- data/lib/hecks/ports/authentication.rb +50 -0
- data/lib/hecks/ports/authorization.port +4 -0
- data/lib/hecks/ports/authorization.rb +59 -0
- data/lib/hecks/ports/clock.port +4 -0
- data/lib/hecks/ports/clock.rb +62 -0
- data/lib/hecks/ports/extraction.port +4 -0
- data/lib/hecks/ports/extraction.rb +37 -0
- data/lib/hecks/ports/identity_assignment.port +4 -0
- data/lib/hecks/ports/identity_assignment.rb +45 -0
- data/lib/hecks/ports/identity_generation.port +4 -0
- data/lib/hecks/ports/identity_generation.rb +49 -0
- data/lib/hecks/ports/identity_resolution.port +4 -0
- data/lib/hecks/ports/identity_resolution.rb +40 -0
- data/lib/hecks/ports/loading.port +4 -0
- data/lib/hecks/ports/loading.rb +13 -0
- data/lib/hecks/ports/persistence/append_only.rb +102 -0
- data/lib/hecks/ports/persistence/binding_policy.rb +56 -0
- data/lib/hecks/ports/persistence/execution.rb +18 -0
- data/lib/hecks/ports/persistence/lineage.rb +277 -0
- data/lib/hecks/ports/persistence/null_saga_store.rb +25 -0
- data/lib/hecks/ports/persistence/remote_runtime.rb +42 -0
- data/lib/hecks/ports/persistence/repository_factory.rb +30 -0
- data/lib/hecks/ports/persistence.port +4 -0
- data/lib/hecks/ports/persistence.rb +39 -0
- data/lib/hecks/ports/projection.port +4 -0
- data/lib/hecks/ports/projection.rb +76 -0
- data/lib/hecks/ports/query/in_memory.rb +60 -0
- data/lib/hecks/ports/query/ordering.rb +41 -0
- data/lib/hecks/ports/query.rb +36 -0
- data/lib/hecks/ports.rb +27 -0
- data/lib/hecks/projections/diagrams.rb +413 -0
- data/lib/hecks/projections/ir.rb +18 -0
- data/lib/hecks/projections/model/deviations.rb +98 -0
- data/lib/hecks/projections/model.rb +145 -0
- data/lib/hecks/projections/oidc.rb +110 -0
- data/lib/hecks/projections/parser_table.rb +159 -0
- data/lib/hecks/projections/reference.rb +38 -0
- data/lib/hecks/projections/shape.rb +31 -0
- data/lib/hecks/projections/statements.rb +110 -0
- data/lib/hecks/projections/vocabulary.rb +100 -0
- data/lib/hecks/projections.rb +32 -0
- data/lib/hecks/projector/cli_projector.rb +437 -0
- data/lib/hecks/projector/docs_projector.rb +321 -0
- data/lib/hecks/projector/exporter.rb +141 -0
- data/lib/hecks/projector/ir_projector.rb +18 -0
- data/lib/hecks/projector/narrate_projector.rb +243 -0
- data/lib/hecks/projector/target.rb +97 -0
- data/lib/hecks/projector.rb +186 -0
- data/lib/hecks/query_ir.rb +392 -0
- data/lib/hecks/query_specification/common/authorization_spec.rb +9 -0
- data/lib/hecks/query_specification/common/comparators.rb +25 -0
- data/lib/hecks/query_specification/common/comparison.rb +174 -0
- data/lib/hecks/query_specification/common/cursor_spec.rb +9 -0
- data/lib/hecks/query_specification/common/dsl.rb +58 -0
- data/lib/hecks/query_specification/common/inspection_spec.rb +9 -0
- data/lib/hecks/query_specification/common/limit_spec.rb +9 -0
- data/lib/hecks/query_specification/common/null_policy.rb +80 -0
- data/lib/hecks/query_specification/common/null_semantics.rb +11 -0
- data/lib/hecks/query_specification/common/offset_spec.rb +9 -0
- data/lib/hecks/query_specification/common/options.rb +32 -0
- data/lib/hecks/query_specification/common/order_by.rb +9 -0
- data/lib/hecks/query_specification/common/specification.rb +10 -0
- data/lib/hecks/query_specification/common/where_clause.rb +9 -0
- data/lib/hecks/query_specification/field_path.rb +89 -0
- data/lib/hecks/query_specification/hop_path.rb +130 -0
- data/lib/hecks/query_specification/read_model/specification.rb +18 -0
- data/lib/hecks/query_specification.rb +14 -0
- data/lib/hecks/rendering.rb +48 -0
- data/lib/hecks/router/namespace_installer.rb +157 -0
- data/lib/hecks/router.rb +70 -0
- data/lib/hecks/runtime/caller.rb +50 -0
- data/lib/hecks/runtime/capability_graph.rb +44 -0
- data/lib/hecks/runtime/command_interpreter/argument_gate.rb +124 -0
- data/lib/hecks/runtime/command_interpreter/mutation_applier.rb +248 -0
- data/lib/hecks/runtime/command_interpreter.rb +413 -0
- data/lib/hecks/runtime/command_rules/admissibility.rb +307 -0
- data/lib/hecks/runtime/command_rules/arithmetic.rb +254 -0
- data/lib/hecks/runtime/command_rules/authorization.rb +64 -0
- data/lib/hecks/runtime/command_rules/emission.rb +34 -0
- data/lib/hecks/runtime/command_rules/references.rb +181 -0
- data/lib/hecks/runtime/command_rules.rb +28 -0
- data/lib/hecks/runtime/dependency_planning.rb +231 -0
- data/lib/hecks/runtime/dispatcher.rb +286 -0
- data/lib/hecks/runtime/entity_element.rb +253 -0
- data/lib/hecks/runtime/entity_interpreter.rb +228 -0
- data/lib/hecks/runtime/era_check.rb +136 -0
- data/lib/hecks/runtime/era_guard/shape_diff.rb +128 -0
- data/lib/hecks/runtime/era_guard.rb +193 -0
- data/lib/hecks/runtime/era_tamper.rb +61 -0
- data/lib/hecks/runtime/errors.rb +100 -0
- data/lib/hecks/runtime/event.rb +51 -0
- data/lib/hecks/runtime/identity.rb +128 -0
- data/lib/hecks/runtime/instance.rb +120 -0
- data/lib/hecks/runtime/interpreting.rb +69 -0
- data/lib/hecks/runtime/loader.rb +143 -0
- data/lib/hecks/runtime/policy_interpreter.rb +366 -0
- data/lib/hecks/runtime/port_operation_interpreter.rb +210 -0
- data/lib/hecks/runtime/query_interpreter.rb +254 -0
- data/lib/hecks/runtime/reaction_invocation.rb +245 -0
- data/lib/hecks/runtime/read_model_interpreter.rb +266 -0
- data/lib/hecks/runtime/rebuild_sweep.rb +74 -0
- data/lib/hecks/runtime/reference_hop.rb +99 -0
- data/lib/hecks/runtime/refusal_wording.rb +124 -0
- data/lib/hecks/runtime/registry/saga_persistence.rb +70 -0
- data/lib/hecks/runtime/registry/verification.rb +158 -0
- data/lib/hecks/runtime/registry.rb +218 -0
- data/lib/hecks/runtime/remote_dispatcher.rb +143 -0
- data/lib/hecks/runtime/routing.rb +96 -0
- data/lib/hecks/runtime/saga_interpreter/correlation.rb +97 -0
- data/lib/hecks/runtime/saga_interpreter.rb +301 -0
- data/lib/hecks/runtime/storage_shape.rb +120 -0
- data/lib/hecks/runtime/tenant_check.rb +84 -0
- data/lib/hecks/runtime/tenant_scope.rb +55 -0
- data/lib/hecks/runtime/value/admission.rb +112 -0
- data/lib/hecks/runtime/value/coercion.rb +500 -0
- data/lib/hecks/runtime/value/invariant_violation.rb +5 -0
- data/lib/hecks/runtime/value.rb +125 -0
- data/lib/hecks/runtime.rb +95 -0
- data/lib/hecks/translation/audit/approval_digest.rb +31 -0
- data/lib/hecks/translation/audit/layer_one.rb +37 -0
- data/lib/hecks/translation/audit/layer_two.rb +77 -0
- data/lib/hecks/translation/audit/unfed_report.rb +42 -0
- data/lib/hecks/translation/audit.rb +70 -0
- data/lib/hecks/translation/reattest.rb +72 -0
- data/lib/hecks/translation/rule_compiler.rb +120 -0
- data/lib/hecks/translation/scaffold/differ.rb +183 -0
- data/lib/hecks/translation/scaffold/renderer.rb +41 -0
- data/lib/hecks/translation/scaffold/writer.rb +28 -0
- data/lib/hecks/translation/scaffold.rb +30 -0
- data/lib/hecks/translation.rb +11 -0
- data/lib/hecks/version.rb +16 -0
- data/lib/hecks/vocabulary.rb +213 -0
- data/lib/hecks.rb +118 -6
- metadata +401 -222
- data/bin/hecks +0 -7
- data/bin/hecks-package +0 -65
- data/bin/hecks_console +0 -12
- data/bin/hecks_serverless +0 -6
- data/lib/cli/build.rb +0 -14
- data/lib/cli/command_runner.rb +0 -28
- data/lib/cli/console.rb +0 -10
- data/lib/cli/generate.rb +0 -37
- data/lib/cli/hecks-cli.rb +0 -27
- data/lib/cli/test.rb +0 -57
- data/lib/console/commands.rb +0 -8
- data/lib/console/hecks-console.rb +0 -1
- data/lib/packager/README.md +0 -0
- data/lib/packager/app_runner.rb +0 -21
- data/lib/packager/args.rb +0 -26
- data/lib/packager/compatibility/fixnum.rb +0 -6
- data/lib/packager/hecks.rb +0 -39
- data/lib/packager/query_runner.rb +0 -21
- data/lib/packager/resources/Dockerfile +0 -11
- data/lib/packager/resources/app_binary +0 -7
- data/lib/packager/resources/bundle_config +0 -3
- data/lib/packager/resources/traveling-ruby-20150715-2.2.2-linux-x86_64.tar.gz +0 -0
- data/lib/packager/resources/traveling-ruby-20150715-2.2.2-osx.tar.gz +0 -0
- data/lib/serverless/Domain +0 -32
- data/lib/serverless/cli.rb +0 -75
- data/lib/serverless/resources/command_name.js +0 -5
- data/lib/serverless/resources/environment.js +0 -7
- data/lib/serverless/resources/handler.js.tt +0 -28
- data/lib/serverless/resources/run_binary.js +0 -22
- data/lib/serverless/resources/serverless.yml +0 -20
|
@@ -0,0 +1,264 @@
|
|
|
1
|
+
Hecks.bluebook "Bluebook" do
|
|
2
|
+
aggregate "ProcessManager" do
|
|
3
|
+
description "One process manager — what correlates its instances, what starts and ends it, and the states it moves through."
|
|
4
|
+
|
|
5
|
+
reference_to Bluebook
|
|
6
|
+
|
|
7
|
+
# THE CHAPTER IT IS IN, AND ITS NAME — the same shape a policy takes, and for
|
|
8
|
+
# the same reason.
|
|
9
|
+
identified_by :bluebook, :name
|
|
10
|
+
|
|
11
|
+
attribute :name, ProcessManagerName
|
|
12
|
+
attribute :correlates_by, ProcessManagerText
|
|
13
|
+
attribute :starts_on, ProcessManagerText
|
|
14
|
+
attribute :ends_on, ProcessManagerText
|
|
15
|
+
attribute :states, list_of(SagaState)
|
|
16
|
+
# S17, ADR 0026 — Handler nested here (see `entity "Handler"`, below),
|
|
17
|
+
# an entity rather than its own root aggregate. `list_of(Handler)`
|
|
18
|
+
# forward-references it the same way banking's own `attribute :ledger,
|
|
19
|
+
# list_of(LedgerEntry)` names LedgerEntry before it is declared.
|
|
20
|
+
attribute :handlers, list_of(Handler)
|
|
21
|
+
|
|
22
|
+
value_object "ProcessManagerName" do
|
|
23
|
+
attribute :value, String
|
|
24
|
+
invariant("a process manager is named") { !value.to_s.empty? }
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
value_object "ProcessManagerText" do
|
|
28
|
+
attribute :value, String
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
value_object "SagaState" do
|
|
32
|
+
attribute :name, String
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
# S17, ADR 0026 — HandlerText/DispatchText/Binding, hoisted up from
|
|
36
|
+
# the old standalone `aggregate "Handler"`/`aggregate "Dispatch"`. An
|
|
37
|
+
# entity cannot declare its own `value_object` (EntityBuilder has no
|
|
38
|
+
# such method — a piece borrows its owning aggregate's, the same way
|
|
39
|
+
# LedgerEntry borrows Account's Money), so these live here now, at
|
|
40
|
+
# the ROOT, where BOTH `entity "Handler"` and its own nested `entity
|
|
41
|
+
# "Dispatch"` can still reach them — a piece mints no value objects
|
|
42
|
+
# of its own AT ANY DEPTH, so there is exactly one pool however deep
|
|
43
|
+
# the nesting goes (`EntityBuilder#entity`'s own comment).
|
|
44
|
+
value_object "HandlerText" do
|
|
45
|
+
attribute :value, String
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
value_object "DispatchText" do
|
|
49
|
+
attribute :value, String
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
value_object "Binding" do
|
|
53
|
+
attribute :key, String
|
|
54
|
+
attribute :value, String
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
# The way back: everything DECLARED IN the chapter above. The parent
|
|
58
|
+
# reference IS the query.
|
|
59
|
+
# WHERE IT SITS AMONG ITS SIBLINGS. Declaration order is a FACT ABOUT THE
|
|
60
|
+
# SOURCE — the IR is a contract read straight from this file,
|
|
61
|
+
# field for field AND INDEX FOR INDEX. So the language HOLDS it, instead of
|
|
62
|
+
# inheriting it from whatever order a store happens to iterate: an ask that
|
|
63
|
+
# does not say how it is ordered is answered in identity order, which is
|
|
64
|
+
# right for every other ask and fatal for the one that is the SOURCE.
|
|
65
|
+
value_object "Position" do
|
|
66
|
+
attribute :value, Integer
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
attribute :position, Position
|
|
70
|
+
|
|
71
|
+
query "DeclaredIn" do
|
|
72
|
+
attribute :bluebook, ProcessManagerText
|
|
73
|
+
where(bluebook: :bluebook)
|
|
74
|
+
order_by :position
|
|
75
|
+
end
|
|
76
|
+
command "Declare" do
|
|
77
|
+
role "Language"
|
|
78
|
+
goal "Open a process manager on a chapter"
|
|
79
|
+
|
|
80
|
+
reference_to Bluebook
|
|
81
|
+
attribute :name, ProcessManagerName
|
|
82
|
+
attribute :correlates_by, ProcessManagerText
|
|
83
|
+
attribute :starts_on, ProcessManagerText
|
|
84
|
+
# A PROCEDURE NEED NOT DECLARE AN ENDING. The runtime has always held
|
|
85
|
+
# this optional — ProcessManagerBuilder defaults `@ends_on` to nil,
|
|
86
|
+
# validates only correlates_by/starts_on/states/handlers,
|
|
87
|
+
# and fills it only if the line is written. The
|
|
88
|
+
# language was the one saying it was required, and nothing in the corpus
|
|
89
|
+
# had to disagree because every procedure in it happens to end.
|
|
90
|
+
attribute :ends_on, ProcessManagerText, optional: true
|
|
91
|
+
|
|
92
|
+
attribute :position, Position, optional: true
|
|
93
|
+
sets :bluebook
|
|
94
|
+
sets :name
|
|
95
|
+
sets :correlates_by
|
|
96
|
+
sets :starts_on
|
|
97
|
+
sets :ends_on
|
|
98
|
+
sets :position
|
|
99
|
+
emits "SagaDeclared"
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
command "State" do
|
|
103
|
+
role "Language"
|
|
104
|
+
goal "Attach one state to the process manager"
|
|
105
|
+
|
|
106
|
+
attribute :name, ProcessManagerText
|
|
107
|
+
|
|
108
|
+
sets :states, append: { name: :name }
|
|
109
|
+
|
|
110
|
+
emits "SagaStateAttached"
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
# THE HANDLER'S OWN CREATION. S17, ADR 0026 — Handler is a genuine
|
|
114
|
+
# ENTITY now (`entity "Handler"`, below), and an entity is never
|
|
115
|
+
# created through its own dotted verb — banking's own LedgerEntry is
|
|
116
|
+
# created by `Account.LogEntry`, an ordinary append on the OWNER,
|
|
117
|
+
# never by a `LedgerEntry.Declare` of its own
|
|
118
|
+
# (`EntityInterpreter#element_of` only LOCATES an element already on
|
|
119
|
+
# the list — it has no path that creates one). So Handler's creation
|
|
120
|
+
# moved here, onto ProcessManager, mirroring `State` beside it: a
|
|
121
|
+
# bare, aggregate-level append.
|
|
122
|
+
command "Handler" do
|
|
123
|
+
role "Language"
|
|
124
|
+
goal "Open a handler inside a process manager"
|
|
125
|
+
|
|
126
|
+
attribute :event_type, HandlerText
|
|
127
|
+
# A LEG ALWAYS SAYS WHERE IT MOVES FROM. There is no wildcard leg to be
|
|
128
|
+
# optional for: `on "Event", transition: { from => to }` is the only
|
|
129
|
+
# spelling the runtime reads, and it refuses anything else —
|
|
130
|
+
# `single_transition` raises unless the hash holds exactly one from => to
|
|
131
|
+
# pair, so a leg without one
|
|
132
|
+
# is never built at all. `optional: true` here was
|
|
133
|
+
# the language admitting a leg the runtime cannot parse.
|
|
134
|
+
attribute :from_state, HandlerText
|
|
135
|
+
attribute :to_state, HandlerText
|
|
136
|
+
|
|
137
|
+
sets :handlers, append: { event_type: :event_type, from_state: :from_state, to_state: :to_state }
|
|
138
|
+
|
|
139
|
+
emits "LegDeclared"
|
|
140
|
+
end
|
|
141
|
+
|
|
142
|
+
# S17, ADR 0026 — ONE HANDLER, nested rather than its own root
|
|
143
|
+
# aggregate. No `saga` field. It named the old word for a process
|
|
144
|
+
# manager, held nothing — ProcessManagerHandler has no such reader,
|
|
145
|
+
# so every Handler record's saga was empty — and repeated the parent
|
|
146
|
+
# that its own containment already carries. A field that names the
|
|
147
|
+
# wrong thing, holds nothing, and duplicates the reference beside it.
|
|
148
|
+
#
|
|
149
|
+
# `event_type` is an event name, or one of the Trigger vocabulary's
|
|
150
|
+
# members when the leg answers something no aggregate announces — and
|
|
151
|
+
# is Handler's own real, non-positional identity now : a saga answers
|
|
152
|
+
# each event ONCE, so the event names the leg, and the process
|
|
153
|
+
# manager it belongs to is structural (which list this element sits
|
|
154
|
+
# in), not a stored field any more.
|
|
155
|
+
entity "Handler" do
|
|
156
|
+
description "One handler inside a process manager — the event it answers, the state move it makes, and the commands it sends. Nested under the process manager because a handler holds nested dispatches, which hold nested bindings."
|
|
157
|
+
|
|
158
|
+
identified_by HandlerText, as: :event_type
|
|
159
|
+
|
|
160
|
+
attribute :from_state, HandlerText
|
|
161
|
+
attribute :to_state, HandlerText
|
|
162
|
+
# S17, ADR 0026 — Dispatch nested here too (see `entity "Dispatch"`,
|
|
163
|
+
# below), one level further in than Handler itself.
|
|
164
|
+
attribute :dispatches, list_of(Dispatch)
|
|
165
|
+
|
|
166
|
+
# THE DISPATCH'S OWN CREATION — same reason Handler's own creation
|
|
167
|
+
# lives on ProcessManager, one level up: an entity is never created
|
|
168
|
+
# through its own dotted verb. Reached as a DOTTED verb itself
|
|
169
|
+
# (`ProcessManager.Handler.Dispatch`) since Handler, the owner
|
|
170
|
+
# doing the creating here, is an entity too, not a real aggregate
|
|
171
|
+
# with a bare verb of its own to dispatch into.
|
|
172
|
+
command "Dispatch" do
|
|
173
|
+
role "Language"
|
|
174
|
+
goal "Open a dispatch inside a handler"
|
|
175
|
+
|
|
176
|
+
attribute :command_name, DispatchText
|
|
177
|
+
|
|
178
|
+
sets :dispatches, append: { command_name: :command_name }
|
|
179
|
+
|
|
180
|
+
emits "SendDeclared"
|
|
181
|
+
end
|
|
182
|
+
|
|
183
|
+
# S17, ADR 0026 — ONE COMMAND A HANDLER DISPATCHES, nested two
|
|
184
|
+
# levels in rather than its own root aggregate — "no life outside
|
|
185
|
+
# its Handler" (the ADR's own words). The bindings are an open
|
|
186
|
+
# map, which no value object can hold — that was always a reason
|
|
187
|
+
# it could not be one, never a reason it could not be an entity.
|
|
188
|
+
# `command_name` is Dispatch's own real, non-positional identity,
|
|
189
|
+
# the same shape Handler's own `event_type` just took one level up.
|
|
190
|
+
entity "Dispatch" do
|
|
191
|
+
description "One command a handler dispatches, with the arguments it binds. Nested under the handler because the bindings are an open map, which no value object can hold."
|
|
192
|
+
|
|
193
|
+
identified_by DispatchText, as: :command_name
|
|
194
|
+
|
|
195
|
+
attribute :with_spec, list_of(Binding)
|
|
196
|
+
|
|
197
|
+
command "Bind" do
|
|
198
|
+
role "Language"
|
|
199
|
+
goal "Bind one argument of the dispatched command"
|
|
200
|
+
|
|
201
|
+
attribute :key, DispatchText
|
|
202
|
+
attribute :value, DispatchText
|
|
203
|
+
|
|
204
|
+
sets :with_spec, append: { key: :key, value: :value }
|
|
205
|
+
|
|
206
|
+
emits "BindingAttached"
|
|
207
|
+
end
|
|
208
|
+
end
|
|
209
|
+
end
|
|
210
|
+
|
|
211
|
+
# HOW PROCESSMANAGER IS SPELLED. These rows live with the concept
|
|
212
|
+
# they describe; SyntaxBoot discovers every aggregate-local seed table.
|
|
213
|
+
# Contexts represented here: ProcessManager, Handler.
|
|
214
|
+
value_object "KeywordSeed" do
|
|
215
|
+
attribute :word, String
|
|
216
|
+
attribute :context, String, admits: "Syntax::Context"
|
|
217
|
+
attribute :body, String, admits: "Syntax::Body"
|
|
218
|
+
attribute :inner, String
|
|
219
|
+
attribute :opens, String
|
|
220
|
+
attribute :fills, String
|
|
221
|
+
attribute :status, String, default: "admitted", admits: "Syntax::Status"
|
|
222
|
+
attribute :was, String
|
|
223
|
+
attribute :resolves_via, String, default: "", admits: "Syntax::ResolutionScope"
|
|
224
|
+
attribute :disambiguator, String, default: "", admits: "Syntax::Disambiguator"
|
|
225
|
+
|
|
226
|
+
member word: "correlates_by", context: "ProcessManager", body: "none", inner: "", opens: "", fills: "correlates_by"
|
|
227
|
+
member word: "starts_on", context: "ProcessManager", body: "none", inner: "", opens: "", fills: "starts_on"
|
|
228
|
+
member word: "ends_on", context: "ProcessManager", body: "none", inner: "", opens: "", fills: "ends_on"
|
|
229
|
+
member word: "transition", context: "ProcessManager", body: "keywords", inner: "Handler", opens: "Handler", fills: "", calls: "transition_impl"
|
|
230
|
+
member word: "transition", context: "ProcessManager", body: "none", inner: "", opens: "", fills: "", calls: "transition_impl"
|
|
231
|
+
member word: "dispatch", context: "Handler", body: "none", inner: "", opens: "Dispatch", fills: "", calls: "dispatch_impl"
|
|
232
|
+
|
|
233
|
+
end
|
|
234
|
+
|
|
235
|
+
value_object "ArgumentSeed" do
|
|
236
|
+
attribute :keyword, String
|
|
237
|
+
attribute :context, String, admits: "Syntax::Context"
|
|
238
|
+
attribute :at, String
|
|
239
|
+
attribute :named, String
|
|
240
|
+
attribute :kind, String, admits: "Syntax::ArgumentKind"
|
|
241
|
+
attribute :required, String
|
|
242
|
+
attribute :fills, String
|
|
243
|
+
attribute :selects, String
|
|
244
|
+
attribute :pair_key_fills, String
|
|
245
|
+
attribute :pair_value_fills, String
|
|
246
|
+
attribute :pairs_shape, String, admits: "Syntax::PairsShape"
|
|
247
|
+
attribute :status, String, default: "admitted", admits: "Syntax::Status"
|
|
248
|
+
attribute :variadic, String
|
|
249
|
+
attribute :coerce, String
|
|
250
|
+
attribute :blank_message, String
|
|
251
|
+
|
|
252
|
+
member keyword: "correlates_by", context: "ProcessManager", at: "1", named: "", kind: "symbol", required: "true", fills: "correlates_by"
|
|
253
|
+
member keyword: "starts_on", context: "ProcessManager", at: "1", named: "", kind: "text", required: "true", fills: "starts_on"
|
|
254
|
+
member keyword: "ends_on", context: "ProcessManager", at: "1", named: "", kind: "text", required: "true", fills: "ends_on"
|
|
255
|
+
member keyword: "transition", context: "ProcessManager", at: "1", named: "", kind: "pairs", required: "true", fills: "", pair_key_fills: "event_type", pair_value_fills: "to_state", pairs_shape: "fields"
|
|
256
|
+
member keyword: "transition", context: "ProcessManager", at: "", named: "from", kind: "text", required: "true", fills: "from_state"
|
|
257
|
+
member keyword: "transition", context: "ProcessManager", at: "", named: "from", kind: "list", required: "false", fills: "from_state"
|
|
258
|
+
member keyword: "dispatch", context: "Handler", at: "1", named: "", kind: "constant", required: "true", fills: "command_name"
|
|
259
|
+
member keyword: "dispatch", context: "Handler", at: "1", named: "", kind: "text", required: "true", fills: "command_name"
|
|
260
|
+
member keyword: "dispatch", context: "Handler", at: "", named: "with", kind: "pairs", required: "false", fills: "with_spec", pairs_shape: "verbatim"
|
|
261
|
+
|
|
262
|
+
end
|
|
263
|
+
end
|
|
264
|
+
end
|
|
@@ -0,0 +1,267 @@
|
|
|
1
|
+
Hecks.bluebook "Bluebook" do
|
|
2
|
+
aggregate "ReadModel" do
|
|
3
|
+
description "One read model — the aggregate heads it gathers and the reference it hangs from."
|
|
4
|
+
|
|
5
|
+
reference_to Bluebook
|
|
6
|
+
|
|
7
|
+
# THE CHAPTER IT IS IN, AND ITS NAME.
|
|
8
|
+
identified_by :bluebook, :name
|
|
9
|
+
|
|
10
|
+
attribute :name, ReadModelName
|
|
11
|
+
attribute :description, ProjectionPurpose
|
|
12
|
+
attribute :query_name, ReadModelText
|
|
13
|
+
attribute :reference_name, ReadModelText
|
|
14
|
+
attribute :reference_target, ReadModelText
|
|
15
|
+
attribute :aggregate_heads, list_of(Head)
|
|
16
|
+
# The same open map a query carries — see Query's AskOption. A read model
|
|
17
|
+
# inherits every specification option an ask has, so it holds them the same way.
|
|
18
|
+
attribute :options, list_of(ProjectionOption)
|
|
19
|
+
# WHICH of the eligible head's own fields to nest its rows under, in
|
|
20
|
+
# declared order. Rows, not a single value object with N fields — an
|
|
21
|
+
# arbitrary NUMBER of fields, the same reason `aggregate_heads`/
|
|
22
|
+
# `options` are lists rather than fixed attributes.
|
|
23
|
+
attribute :group_by, list_of(GroupByField)
|
|
24
|
+
# `count`/`median_field` are the OTHER two reductions a read model
|
|
25
|
+
# may declare over its one eligible head, siblings of `group_by`
|
|
26
|
+
# rather than of `options` — same permissive `ReadModelText` shape,
|
|
27
|
+
# and the same UNmarked-optional spelling `reference_name`/
|
|
28
|
+
# `reference_target` already use just above (permissiveness lives
|
|
29
|
+
# in `ReadModelText`'s own lack of an invariant, not in an
|
|
30
|
+
# `optional:` flag this chapter's aggregate-level attributes never
|
|
31
|
+
# carry) — "true"/"" for `count`, a field name or "" for
|
|
32
|
+
# `median_field`, both legitimately absent on a read model that
|
|
33
|
+
# declares neither.
|
|
34
|
+
attribute :count, ReadModelText, optional: true
|
|
35
|
+
attribute :median_field, ReadModelText, optional: true
|
|
36
|
+
|
|
37
|
+
value_object "ReadModelName" do
|
|
38
|
+
attribute :value, String
|
|
39
|
+
invariant("a read model is named") { !value.to_s.empty? }
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
value_object "ReadModelText" do
|
|
43
|
+
# deliberately permissive : query_name / ref_name / ref_target are
|
|
44
|
+
# legitimately empty on a read model that has not named them yet
|
|
45
|
+
attribute :value, String
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
value_object "ProjectionPurpose" do
|
|
49
|
+
attribute :value, String
|
|
50
|
+
invariant("a description says something") { !value.to_s.empty? }
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
value_object "Head" do
|
|
54
|
+
attribute :aggregate, String
|
|
55
|
+
attribute :as, String
|
|
56
|
+
attribute :many, String
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
value_object "ProjectionOption" do
|
|
60
|
+
attribute :option, String
|
|
61
|
+
attribute :key, String
|
|
62
|
+
attribute :value, String
|
|
63
|
+
attribute :at, String
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
value_object "GroupByField" do
|
|
67
|
+
attribute :field, String
|
|
68
|
+
invariant("a group_by field is named") { !field.to_s.empty? }
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
# The way back: everything DECLARED IN the chapter above. The parent
|
|
72
|
+
# reference IS the query.
|
|
73
|
+
# WHERE IT SITS AMONG ITS SIBLINGS. Declaration order is a FACT ABOUT THE
|
|
74
|
+
# SOURCE — the IR is a contract read straight from this file,
|
|
75
|
+
# field for field AND INDEX FOR INDEX. So the language HOLDS it, instead of
|
|
76
|
+
# inheriting it from whatever order a store happens to iterate: an ask that
|
|
77
|
+
# does not say how it is ordered is answered in identity order, which is
|
|
78
|
+
# right for every other ask and fatal for the one that is the SOURCE.
|
|
79
|
+
value_object "Position" do
|
|
80
|
+
attribute :value, Integer
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
attribute :position, Position
|
|
84
|
+
|
|
85
|
+
query "DeclaredIn" do
|
|
86
|
+
attribute :bluebook, ReadModelText
|
|
87
|
+
where(bluebook: :bluebook)
|
|
88
|
+
order_by :position
|
|
89
|
+
end
|
|
90
|
+
command "Declare" do
|
|
91
|
+
role "Language"
|
|
92
|
+
goal "Open a read model on a chapter"
|
|
93
|
+
|
|
94
|
+
reference_to Bluebook
|
|
95
|
+
attribute :name, ReadModelName
|
|
96
|
+
attribute :description, ProjectionPurpose, optional: true
|
|
97
|
+
attribute :query_name, ReadModelText
|
|
98
|
+
# Both optional now — a ROOTLESS read model (no `reference_to`
|
|
99
|
+
# declared at all) has neither. Permanently empty, not "not yet
|
|
100
|
+
# set" — see Gather's own comment below for why that distinction
|
|
101
|
+
# matters.
|
|
102
|
+
attribute :reference_name, ReadModelText, optional: true
|
|
103
|
+
attribute :reference_target, ReadModelText, optional: true
|
|
104
|
+
|
|
105
|
+
attribute :position, Position, optional: true
|
|
106
|
+
sets :bluebook
|
|
107
|
+
sets :name
|
|
108
|
+
sets :description
|
|
109
|
+
sets :query_name
|
|
110
|
+
sets :reference_name
|
|
111
|
+
sets :reference_target
|
|
112
|
+
sets :position
|
|
113
|
+
emits "ProjectionDeclared"
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
command "Gather" do
|
|
117
|
+
role "Language"
|
|
118
|
+
goal "Attach one aggregate head to the read model"
|
|
119
|
+
|
|
120
|
+
# A HEAD IS THE AGGREGATE IT NAMES. There is no head with nothing gathered:
|
|
121
|
+
# `add_aggregate_head` is only ever reached from an `include Target`,
|
|
122
|
+
# so the builder cannot produce one
|
|
123
|
+
# without it — the field is a plain
|
|
124
|
+
# required, non-empty name. `as` and
|
|
125
|
+
# `many` are both DERIVED from it when the author does not spell them, which
|
|
126
|
+
# is the clearest statement that it is the part that cannot be missing.
|
|
127
|
+
attribute :aggregate, ReadModelText
|
|
128
|
+
attribute :as, ReadModelText
|
|
129
|
+
attribute :many, ReadModelText
|
|
130
|
+
|
|
131
|
+
# NOT "reference_target must already be set" anymore — reference_target
|
|
132
|
+
# is fixed forever at Declare time (nothing ever changes it later), so
|
|
133
|
+
# that rule was really "this read model must have SOME reference, ever"
|
|
134
|
+
# — exactly the constraint a ROOTLESS read model (bulk, no root,
|
|
135
|
+
# `group_by`'s own real use) deliberately doesn't meet, permanently,
|
|
136
|
+
# on purpose, not by omission. Removed rather than relaxed: there is
|
|
137
|
+
# no runtime fact left here that distinguishes "forgot to declare a
|
|
138
|
+
# reference" from "declared rootless on purpose" — both look
|
|
139
|
+
# identical (`reference_target` empty) by the time Gather is judged.
|
|
140
|
+
|
|
141
|
+
sets :aggregate_heads, append: { aggregate: :aggregate, as: :as, many: :many }
|
|
142
|
+
|
|
143
|
+
emits "HeadGathered"
|
|
144
|
+
end
|
|
145
|
+
|
|
146
|
+
command "GroupBy" do
|
|
147
|
+
role "Language"
|
|
148
|
+
goal "Nest one collection's own rows by one of its own fields"
|
|
149
|
+
|
|
150
|
+
attribute :field, ReadModelText
|
|
151
|
+
|
|
152
|
+
given("a group_by field is named") { !field.value.to_s.empty? }
|
|
153
|
+
|
|
154
|
+
sets :group_by, append: { field: :field }
|
|
155
|
+
|
|
156
|
+
emits "GroupByFieldAdded"
|
|
157
|
+
end
|
|
158
|
+
|
|
159
|
+
# `count`/`median` are LATE-SET scalars, the same shape `Lifecycle`'s
|
|
160
|
+
# own `state_field`/`state_start` already are on `Aggregate`
|
|
161
|
+
# (aggregate.bluebook) — a command carrying its own value and a bare
|
|
162
|
+
# `sets field, to: field` copying it onto the record, rather
|
|
163
|
+
# than an `append:` (they are not lists, and there is only ever one
|
|
164
|
+
# of each). `count`/`median_field` are declared here, not folded
|
|
165
|
+
# into `Declare`, for the same reason `GroupBy` is its own command
|
|
166
|
+
# above: neither is known until the DSL body runs past `include`.
|
|
167
|
+
command "Count" do
|
|
168
|
+
role "Language"
|
|
169
|
+
goal "Mark the read model as a bare row count over its one eligible collection"
|
|
170
|
+
|
|
171
|
+
|
|
172
|
+
sets :count
|
|
173
|
+
|
|
174
|
+
emits "CountDeclared"
|
|
175
|
+
end
|
|
176
|
+
|
|
177
|
+
command "Median" do
|
|
178
|
+
role "Language"
|
|
179
|
+
goal "Mark the read model as the median of one numeric field across its one eligible collection"
|
|
180
|
+
|
|
181
|
+
|
|
182
|
+
given("a median field is named") { !median_field.value.to_s.empty? }
|
|
183
|
+
|
|
184
|
+
sets :median_field
|
|
185
|
+
|
|
186
|
+
emits "MedianFieldSet"
|
|
187
|
+
end
|
|
188
|
+
|
|
189
|
+
command "Option" do
|
|
190
|
+
role "Language"
|
|
191
|
+
goal "Attach one part of one specification option to the read model"
|
|
192
|
+
|
|
193
|
+
attribute :option, ReadModelText
|
|
194
|
+
attribute :key, ReadModelText
|
|
195
|
+
# Same reading as Query.Option above — an option key may stand alone.
|
|
196
|
+
attribute :value, ReadModelText, optional: true
|
|
197
|
+
attribute :at, ReadModelText, optional: true
|
|
198
|
+
|
|
199
|
+
given("an option is named") { !option.value.to_s.empty? }
|
|
200
|
+
|
|
201
|
+
sets :options, append: { option: :option, key: :key, value: :value, at: :at }
|
|
202
|
+
|
|
203
|
+
emits "OptionAttached"
|
|
204
|
+
end
|
|
205
|
+
|
|
206
|
+
# HOW READMODEL IS SPELLED. These rows live with the concept
|
|
207
|
+
# they describe; SyntaxBoot discovers every aggregate-local seed table.
|
|
208
|
+
# Contexts represented here: ReadModel.
|
|
209
|
+
value_object "KeywordSeed" do
|
|
210
|
+
attribute :word, String
|
|
211
|
+
attribute :context, String, admits: "Syntax::Context"
|
|
212
|
+
attribute :body, String, admits: "Syntax::Body"
|
|
213
|
+
attribute :inner, String
|
|
214
|
+
attribute :opens, String
|
|
215
|
+
attribute :fills, String
|
|
216
|
+
attribute :status, String, default: "admitted", admits: "Syntax::Status"
|
|
217
|
+
attribute :was, String
|
|
218
|
+
attribute :resolves_via, String, default: "", admits: "Syntax::ResolutionScope"
|
|
219
|
+
attribute :disambiguator, String, default: "", admits: "Syntax::Disambiguator"
|
|
220
|
+
|
|
221
|
+
member word: "description", context: "ReadModel", body: "none", inner: "", opens: "", fills: "description"
|
|
222
|
+
member word: "reference_to", context: "ReadModel", body: "none", inner: "", opens: "", fills: "reference_target", calls: "reference_to_impl"
|
|
223
|
+
member word: "include", context: "ReadModel", body: "none", inner: "", opens: "", fills: "aggregate_heads", calls: "include_impl"
|
|
224
|
+
member word: "group_by", context: "ReadModel", body: "none", inner: "", opens: "", fills: "group_by", calls: "group_by_impl"
|
|
225
|
+
member word: "count", context: "ReadModel", body: "none", inner: "", opens: "", fills: "count"
|
|
226
|
+
member word: "median", context: "ReadModel", body: "none", inner: "", opens: "", fills: "median_field"
|
|
227
|
+
member word: "where", context: "ReadModel", body: "none", inner: "", opens: "", fills: "options", calls: "where_impl"
|
|
228
|
+
member word: "order_by", context: "ReadModel", body: "none", inner: "", opens: "", fills: "options", calls: "order_by_impl"
|
|
229
|
+
member word: "authorize", context: "ReadModel", body: "none", inner: "", opens: "", fills: "options", calls: "authorize_impl"
|
|
230
|
+
member word: "inspect_query", context: "ReadModel", body: "none", inner: "", opens: "", fills: "options"
|
|
231
|
+
|
|
232
|
+
end
|
|
233
|
+
|
|
234
|
+
value_object "ArgumentSeed" do
|
|
235
|
+
attribute :keyword, String
|
|
236
|
+
attribute :context, String, admits: "Syntax::Context"
|
|
237
|
+
attribute :at, String
|
|
238
|
+
attribute :named, String
|
|
239
|
+
attribute :kind, String, admits: "Syntax::ArgumentKind"
|
|
240
|
+
attribute :required, String
|
|
241
|
+
attribute :fills, String
|
|
242
|
+
attribute :selects, String
|
|
243
|
+
attribute :pair_key_fills, String
|
|
244
|
+
attribute :pair_value_fills, String
|
|
245
|
+
attribute :pairs_shape, String, admits: "Syntax::PairsShape"
|
|
246
|
+
attribute :status, String, default: "admitted", admits: "Syntax::Status"
|
|
247
|
+
attribute :variadic, String
|
|
248
|
+
attribute :coerce, String
|
|
249
|
+
attribute :blank_message, String
|
|
250
|
+
|
|
251
|
+
member keyword: "description", context: "ReadModel", at: "1", named: "", kind: "text", required: "true", fills: "description", coerce: "false"
|
|
252
|
+
member keyword: "reference_to", context: "ReadModel", at: "1", named: "", kind: "constant", required: "true", fills: "reference_target"
|
|
253
|
+
member keyword: "reference_to", context: "ReadModel", at: "", named: "as", kind: "symbol", required: "false", fills: "reference_name"
|
|
254
|
+
member keyword: "include", context: "ReadModel", at: "1", named: "", kind: "constant", required: "true", fills: "aggregate"
|
|
255
|
+
member keyword: "include", context: "ReadModel", at: "", named: "as", kind: "symbol", required: "false", fills: "as"
|
|
256
|
+
member keyword: "group_by", context: "ReadModel", at: "1", named: "", kind: "symbol", required: "true", fills: "group_by", variadic: "true"
|
|
257
|
+
member keyword: "median", context: "ReadModel", at: "1", named: "", kind: "symbol", required: "true", fills: "median_field"
|
|
258
|
+
member keyword: "where", context: "ReadModel", at: "1", named: "", kind: "pairs", required: "true", fills: ""
|
|
259
|
+
member keyword: "order_by", context: "ReadModel", at: "1", named: "", kind: "symbol", required: "true", fills: "field"
|
|
260
|
+
member keyword: "order_by", context: "ReadModel", at: "2", named: "", kind: "symbol", required: "false", fills: "direction"
|
|
261
|
+
member keyword: "authorize", context: "ReadModel", at: "1", named: "", kind: "symbol", required: "true", fills: "policy"
|
|
262
|
+
member keyword: "authorize", context: "ReadModel", at: "", named: "tenant", kind: "symbol", required: "false", fills: "tenant"
|
|
263
|
+
member keyword: "inspect_query", context: "ReadModel", at: "1", named: "", kind: "symbol", required: "false", fills: "mode"
|
|
264
|
+
|
|
265
|
+
end
|
|
266
|
+
end
|
|
267
|
+
end
|