GeneralManager 0.86.0__tar.gz → 0.86.2__tar.gz
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.
- {generalmanager-0.86.0/src/GeneralManager.egg-info → generalmanager-0.86.2}/PKG-INFO +1 -1
- {generalmanager-0.86.0 → generalmanager-0.86.2}/pyproject.toml +1 -1
- {generalmanager-0.86.0 → generalmanager-0.86.2/src/GeneralManager.egg-info}/PKG-INFO +1 -1
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/api/graphql.py +76 -30
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/cache/data_change_context.py +41 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/cache/signals.py +22 -11
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/interface/capabilities/orm/mutations.py +33 -2
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/interface/capabilities/orm_utils/update_state.py +11 -3
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/workflow/signal_bridge.py +4 -2
- {generalmanager-0.86.0 → generalmanager-0.86.2}/LICENSE +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/README.md +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/setup.cfg +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/GeneralManager.egg-info/SOURCES.txt +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/GeneralManager.egg-info/dependency_links.txt +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/GeneralManager.egg-info/requires.txt +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/GeneralManager.egg-info/top_level.txt +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/__init__.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/_types/__init__.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/_types/api.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/_types/bucket.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/_types/cache.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/_types/dataframes.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/_types/factory.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/_types/general_manager.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/_types/interface.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/_types/manager.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/_types/measurement.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/_types/permission.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/_types/rule.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/_types/search.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/_types/utils.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/api/__init__.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/api/graphql_as_of.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/api/graphql_errors.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/api/graphql_groups.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/api/graphql_identifiers.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/api/graphql_mutations.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/api/graphql_ordering.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/api/graphql_output.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/api/graphql_prefetch.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/api/graphql_relations.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/api/graphql_resolvers.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/api/graphql_search.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/api/graphql_subscription_consumer.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/api/graphql_subscriptions.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/api/graphql_type.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/api/graphql_view.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/api/graphql_warmup.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/api/graphql_warmup_registry.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/api/graphql_warmup_tasks.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/api/mutation.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/api/notification_batching.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/api/property.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/api/registry.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/api/remote_api.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/api/remote_invalidation.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/api/remote_invalidation_client.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/apps.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/as_of.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/bootstrap.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/bucket/__init__.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/bucket/_materialized_bucket.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/bucket/_ordering.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/bucket/base_bucket.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/bucket/calculation_bucket.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/bucket/database_bucket.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/bucket/excel_bucket.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/bucket/group_bucket.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/bucket/indexing.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/bucket/projection.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/bucket/request_bucket.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/cache/__init__.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/cache/_dependency_graph.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/cache/batch_refresh.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/cache/cache_decorator.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/cache/cache_tracker.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/cache/dependency_cache.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/cache/dependency_index.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/cache/dependency_matching.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/cache/dependency_publish.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/cache/dependency_shards.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/cache/model_dependency_collector.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/cache/run_context.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/cache/run_context_lru.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/cache/transaction_barrier.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/chat/__init__.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/chat/audit.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/chat/bootstrap.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/chat/checks.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/chat/consumer.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/chat/context.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/chat/errors.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/chat/evals/__init__.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/chat/evals/__main__.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/chat/evals/baseline.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/chat/evals/datasets/basic_queries.yaml +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/chat/evals/datasets/demo_readiness.yaml +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/chat/evals/datasets/edge_cases.yaml +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/chat/evals/datasets/follow_ups.yaml +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/chat/evals/datasets/large_schema.yaml +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/chat/evals/datasets/multi_hop.yaml +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/chat/evals/datasets/planned_orchestration.yaml +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/chat/evals/diagnostics.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/chat/evals/fingerprints.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/chat/evals/fixtures.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/chat/evals/judges/__init__.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/chat/evals/judges/answer_quality.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/chat/evals/judges/contract.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/chat/evals/judges/result_accuracy.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/chat/evals/judges/tool_sequence.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/chat/evals/readiness.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/chat/evals/runner.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/chat/evals/traces.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/chat/grounding.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/chat/models.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/chat/planned/__init__.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/chat/planned/budget.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/chat/planned/calculations.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/chat/planned/catalog.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/chat/planned/config.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/chat/planned/events.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/chat/planned/evidence.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/chat/planned/models.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/chat/planned/planner.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/chat/planned/provider_calls.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/chat/planned/resolver.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/chat/planned/routing.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/chat/planned/scheduler.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/chat/planned/synthesis.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/chat/planned/validation.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/chat/providers/__init__.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/chat/providers/_shared.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/chat/providers/anthropic.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/chat/providers/base.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/chat/providers/google.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/chat/providers/ollama.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/chat/providers/openai.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/chat/rate_limits.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/chat/routing.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/chat/schema_index.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/chat/settings.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/chat/signals.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/chat/system_prompt.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/chat/tool_metadata.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/chat/tools.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/chat/turns.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/chat/views.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/conf.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/dataframes/__init__.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/dataframes/measurements.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/factory/__init__.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/factory/auto_factory.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/factory/factories.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/factory/factory_methods.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/interface/__init__.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/interface/base_interface.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/interface/bundles/__init__.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/interface/bundles/calculation.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/interface/bundles/database.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/interface/bundles/excel.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/interface/bundles/remote_manager.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/interface/bundles/request.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/interface/capabilities/__init__.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/interface/capabilities/base.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/interface/capabilities/builtin.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/interface/capabilities/calculation/__init__.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/interface/capabilities/calculation/_compat.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/interface/capabilities/calculation/input_resolution.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/interface/capabilities/calculation/lifecycle.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/interface/capabilities/configuration.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/interface/capabilities/core/observability.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/interface/capabilities/core/utils.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/interface/capabilities/excel/__init__.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/interface/capabilities/exceptions.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/interface/capabilities/existing_model/__init__.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/interface/capabilities/existing_model/_compat.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/interface/capabilities/existing_model/resolution.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/interface/capabilities/factory.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/interface/capabilities/orm/__init__.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/interface/capabilities/orm/_compat.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/interface/capabilities/orm/bulk.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/interface/capabilities/orm/create_many.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/interface/capabilities/orm/history.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/interface/capabilities/orm/lifecycle.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/interface/capabilities/orm/support.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/interface/capabilities/orm_utils/__init__.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/interface/capabilities/orm_utils/django_manager_utils.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/interface/capabilities/orm_utils/field_descriptors.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/interface/capabilities/orm_utils/payload_normalizer.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/interface/capabilities/read_only/__init__.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/interface/capabilities/read_only/_compat.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/interface/capabilities/read_only/_types.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/interface/capabilities/read_only/lifecycle.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/interface/capabilities/read_only/management.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/interface/capabilities/registry.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/interface/capabilities/remote_manager.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/interface/capabilities/request/__init__.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/interface/excel.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/interface/excel_store.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/interface/excel_workbook.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/interface/infrastructure/__init__.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/interface/infrastructure/startup_hooks.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/interface/infrastructure/system_checks.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/interface/interfaces/__init__.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/interface/interfaces/calculation.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/interface/interfaces/database.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/interface/interfaces/excel.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/interface/interfaces/existing_model.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/interface/interfaces/read_only.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/interface/interfaces/remote_manager.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/interface/interfaces/request.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/interface/manifests/__init__.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/interface/manifests/capability_builder.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/interface/manifests/capability_manifest.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/interface/manifests/capability_models.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/interface/orm_interface.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/interface/requests.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/interface/utils/__init__.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/interface/utils/database_interface_protocols.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/interface/utils/errors.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/interface/utils/history.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/interface/utils/models.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/logging.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/management/commands/chat_cleanup.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/management/commands/cleanup_upload_intents.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/management/commands/graphql_warmup.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/management/commands/graphql_warmup_refresh_due.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/management/commands/search_index.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/management/commands/search_reconcile.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/management/commands/seed_manager_landscape.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/management/commands/shell.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/management/commands/sync_read_only.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/management/commands/workflow_drain_outbox.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/management/commands/workflow_replay_dead_letters.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/manager/__init__.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/manager/bulk_create.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/manager/general_manager.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/manager/group_manager.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/manager/input.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/manager/meta.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/measurement/__init__.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/measurement/measurement.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/measurement/measurement_field.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/metrics/__init__.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/metrics/graphql.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/migrations/0001_initial.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/migrations/0002_workflow_outbox_scaling_indexes.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/migrations/0003_workflow_execution_correlation_constraint.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/migrations/0004_chat_persistence_models.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/migrations/0004_search_index_state.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/migrations/0005_merge_chat_search.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/migrations/0006_chat_pending_confirmation_scoped_ids.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/migrations/0007_upload_intent.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/migrations/0008_upload_finalization_versions.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/migrations/0009_upload_cleanup_state.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/migrations/0010_chat_pending_confirmation_portable_uniqueness.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/migrations/0011_search_index_state_dirty_generation.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/migrations/0012_chat_context_watermarks.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/migrations/__init__.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/models.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/permission/__init__.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/permission/audit.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/permission/base_permission.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/permission/graphql_capabilities.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/permission/manager_based_permission.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/permission/mutation_permission.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/permission/permission_checks.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/permission/permission_data_manager.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/permission/utils.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/public_api_registry.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/py.typed +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/rule/__init__.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/rule/handler.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/rule/rule.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/search/__init__.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/search/async_tasks.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/search/backend.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/search/backend_registry.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/search/backends/__init__.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/search/backends/dev.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/search/backends/meilisearch.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/search/backends/opensearch.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/search/backends/typesense.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/search/checks.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/search/config.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/search/identity.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/search/indexer.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/search/invalidation.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/search/m2m_invalidation.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/search/models.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/search/reconciliation.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/search/registry.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/search/tasks.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/search/utils.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/seeding/__init__.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/seeding/manager_landscape.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/uploads/__init__.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/uploads/adapters.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/uploads/checks.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/uploads/config.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/uploads/errors.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/uploads/finalization.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/uploads/graphql.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/uploads/graphql_types.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/uploads/metrics.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/uploads/models.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/uploads/public.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/uploads/s3.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/uploads/services.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/uploads/tokens.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/uploads/types.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/uploads/urls.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/uploads/views.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/utils/__init__.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/utils/_args_to_kwargs.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/utils/_cache_key_encoder.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/utils/_make_cache_key.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/utils/_none_to_zero.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/utils/filter_parser.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/utils/format_string.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/utils/json_encoder.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/utils/path_mapping.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/utils/public_api.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/utils/testing.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/utils/type_checks.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/workflow/__init__.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/workflow/actions.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/workflow/backend_registry.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/workflow/backends/__init__.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/workflow/backends/celery.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/workflow/backends/local.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/workflow/backends/n8n.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/workflow/config.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/workflow/engine.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/workflow/event_registry.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/workflow/events.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/workflow/models.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/workflow/tasks.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/workflow/telemetry.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/tests/test_settings.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/tests/test_urls.py +0 -0
- {generalmanager-0.86.0 → generalmanager-0.86.2}/tests/testing_asgi.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: GeneralManager
|
|
3
|
-
Version: 0.86.
|
|
3
|
+
Version: 0.86.2
|
|
4
4
|
Summary: Modular Django-based data management framework with ORM, GraphQL, fine-grained permissions, rule validation, calculations and caching.
|
|
5
5
|
Author-email: Tim Kleindick <tkleindick@yahoo.de>
|
|
6
6
|
License: MIT License
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "GeneralManager"
|
|
7
|
-
version = "0.86.
|
|
7
|
+
version = "0.86.2"
|
|
8
8
|
description = "Modular Django-based data management framework with ORM, GraphQL, fine-grained permissions, rule validation, calculations and caching."
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
authors = [{ name = "Tim Kleindick", email = "tkleindick@yahoo.de" }]
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: GeneralManager
|
|
3
|
-
Version: 0.86.
|
|
3
|
+
Version: 0.86.2
|
|
4
4
|
Summary: Modular Django-based data management framework with ORM, GraphQL, fine-grained permissions, rule validation, calculations and caching.
|
|
5
5
|
Author-email: Tim Kleindick <tkleindick@yahoo.de>
|
|
6
6
|
License: MIT License
|
|
@@ -47,6 +47,7 @@ from general_manager.bucket._materialized_bucket import MaterializedBucket
|
|
|
47
47
|
from general_manager.bucket.group_bucket import GroupBucket
|
|
48
48
|
from general_manager.bucket.request_bucket import RequestBucket
|
|
49
49
|
from general_manager.bucket.indexing import freeze_bucket_index_value
|
|
50
|
+
from general_manager.cache.cache_tracker import DependencyTracker
|
|
50
51
|
from general_manager.cache.dependency_index import (
|
|
51
52
|
Dependency,
|
|
52
53
|
)
|
|
@@ -116,6 +117,7 @@ from general_manager.api.graphql_resolvers import (
|
|
|
116
117
|
apply_pagination as _apply_pagination_fn,
|
|
117
118
|
apply_grouping as _apply_grouping_fn,
|
|
118
119
|
check_read_permission as _check_read_permission_fn,
|
|
120
|
+
check_read_permission_for_user as _check_read_permission_for_user_fn,
|
|
119
121
|
can_read_instance_for_user as _can_read_instance_for_user_fn,
|
|
120
122
|
create_measurement_resolver as _create_measurement_resolver_fn,
|
|
121
123
|
create_normal_resolver as _create_normal_resolver_fn,
|
|
@@ -2391,6 +2393,36 @@ class GraphQL:
|
|
|
2391
2393
|
raise
|
|
2392
2394
|
return item if readable else None
|
|
2393
2395
|
|
|
2396
|
+
@classmethod
|
|
2397
|
+
def _prepare_detail_subscription(
|
|
2398
|
+
cls,
|
|
2399
|
+
manager_class: type[GeneralManager],
|
|
2400
|
+
identification: GraphQLIdentification,
|
|
2401
|
+
user: object,
|
|
2402
|
+
*,
|
|
2403
|
+
property_names: Iterable[str] = (),
|
|
2404
|
+
) -> tuple[GeneralManager, set[Dependency]] | None:
|
|
2405
|
+
"""Hydrate and authorize before priming selected readable properties.
|
|
2406
|
+
|
|
2407
|
+
Call in a worker thread: construction, native permissions and property
|
|
2408
|
+
reads may all access the ORM. Only hydration errors are suppressed;
|
|
2409
|
+
permission-backend and property failures must fail the stream closed.
|
|
2410
|
+
"""
|
|
2411
|
+
with DependencyTracker() as dependencies:
|
|
2412
|
+
try:
|
|
2413
|
+
instance, _ = cls._instantiate_manager(manager_class, identification)
|
|
2414
|
+
except SUBSCRIPTION_HYDRATION_ERRORS:
|
|
2415
|
+
return None
|
|
2416
|
+
if not _can_read_instance_for_user_fn(instance, user):
|
|
2417
|
+
return None
|
|
2418
|
+
readable_properties = [
|
|
2419
|
+
name
|
|
2420
|
+
for name in property_names
|
|
2421
|
+
if _check_read_permission_for_user_fn(instance, user, name)
|
|
2422
|
+
]
|
|
2423
|
+
cls._prime_graphql_properties(instance, readable_properties)
|
|
2424
|
+
return instance, dependencies
|
|
2425
|
+
|
|
2394
2426
|
@classmethod
|
|
2395
2427
|
def _add_subscription_field(
|
|
2396
2428
|
cls,
|
|
@@ -2411,7 +2443,7 @@ class GraphQL:
|
|
|
2411
2443
|
|
|
2412
2444
|
Notes:
|
|
2413
2445
|
- The subscribe function requires an available channel layer and subscribes the caller to channel groups derived from the instance identification and its resolved dependencies.
|
|
2414
|
-
-
|
|
2446
|
+
- Detail events contain an authorized current instance and an action; unavailable or unreadable targets terminate the detail stream.
|
|
2415
2447
|
- On termination the subscription cleans up listener tasks and unsubscribes from channel groups.
|
|
2416
2448
|
"""
|
|
2417
2449
|
manager_field_name = pascal_to_snake(generalManagerClass.__name__)
|
|
@@ -2451,27 +2483,30 @@ class GraphQL:
|
|
|
2451
2483
|
"""
|
|
2452
2484
|
Stream subscription events for a specific manager instance identified by the provided arguments.
|
|
2453
2485
|
|
|
2454
|
-
|
|
2455
|
-
|
|
2456
|
-
|
|
2457
|
-
|
|
2458
|
-
|
|
2459
|
-
Returns:
|
|
2460
|
-
AsyncIterator[SubscriptionEvent]: An asynchronous iterator that first yields a snapshot event and then yields update events; each event's `item` is the manager instance or `None` if it could not be instantiated.
|
|
2486
|
+
Authorize the request user before property priming and registration.
|
|
2487
|
+
Recheck access before each event; unavailable or unreadable targets
|
|
2488
|
+
end the iterator without forwarding the queued action. Closing the
|
|
2489
|
+
iterator removes its listeners and channel memberships.
|
|
2461
2490
|
"""
|
|
2462
2491
|
identification_copy = deepcopy(identification)
|
|
2463
2492
|
property_names = cls._subscription_property_names(info, generalManagerClass)
|
|
2493
|
+
subscription_user = info.context.user
|
|
2464
2494
|
try:
|
|
2465
|
-
|
|
2466
|
-
cls.
|
|
2495
|
+
prepared = await asyncio.to_thread(
|
|
2496
|
+
cls._prepare_detail_subscription,
|
|
2467
2497
|
generalManagerClass,
|
|
2468
2498
|
identification_copy,
|
|
2469
|
-
|
|
2499
|
+
subscription_user,
|
|
2470
2500
|
property_names=property_names,
|
|
2471
2501
|
)
|
|
2472
2502
|
except Exception as exc: # pragma: no cover - bubbled to GraphQL
|
|
2473
2503
|
raise GraphQLError(str(exc)) from exc
|
|
2474
2504
|
|
|
2505
|
+
if prepared is None:
|
|
2506
|
+
message = "Subscription target is unavailable or not readable."
|
|
2507
|
+
raise GraphQLError(message)
|
|
2508
|
+
instance, dependency_records = prepared
|
|
2509
|
+
|
|
2475
2510
|
try:
|
|
2476
2511
|
channel_layer = cast(
|
|
2477
2512
|
BaseChannelLayer, cls._get_channel_layer(strict=True)
|
|
@@ -2498,15 +2533,16 @@ class GraphQL:
|
|
|
2498
2533
|
group_names.add(cls._refresh_group_name(dependency_class))
|
|
2499
2534
|
|
|
2500
2535
|
async def event_stream() -> AsyncIterator[SubscriptionEvent]:
|
|
2501
|
-
"""
|
|
2502
|
-
|
|
2503
|
-
|
|
2504
|
-
|
|
2505
|
-
|
|
2506
|
-
|
|
2507
|
-
|
|
2508
|
-
|
|
2509
|
-
|
|
2536
|
+
"""Deliver authorized events and clean up on every exit path."""
|
|
2537
|
+
# The iterator may be consumed long after subscribe() returns.
|
|
2538
|
+
prepared = await asyncio.to_thread(
|
|
2539
|
+
cls._prepare_detail_subscription,
|
|
2540
|
+
generalManagerClass,
|
|
2541
|
+
identification_copy,
|
|
2542
|
+
subscription_user,
|
|
2543
|
+
)
|
|
2544
|
+
if prepared is None:
|
|
2545
|
+
return
|
|
2510
2546
|
channel_name = cast(str, await channel_layer.new_channel())
|
|
2511
2547
|
queue: asyncio.Queue[str] = asyncio.Queue[str]()
|
|
2512
2548
|
joined_groups = await _join_subscription_groups(
|
|
@@ -2523,19 +2559,29 @@ class GraphQL:
|
|
|
2523
2559
|
joined_groups,
|
|
2524
2560
|
listener_task,
|
|
2525
2561
|
):
|
|
2562
|
+
# Group registration awaits I/O; access can change meanwhile.
|
|
2563
|
+
prepared = await asyncio.to_thread(
|
|
2564
|
+
cls._prepare_detail_subscription,
|
|
2565
|
+
generalManagerClass,
|
|
2566
|
+
identification_copy,
|
|
2567
|
+
subscription_user,
|
|
2568
|
+
)
|
|
2569
|
+
if prepared is None:
|
|
2570
|
+
return
|
|
2571
|
+
item, _ = prepared
|
|
2526
2572
|
clear_capability_context(info)
|
|
2527
|
-
yield SubscriptionEvent(item=
|
|
2573
|
+
yield SubscriptionEvent(item=item, action="snapshot")
|
|
2528
2574
|
while True:
|
|
2529
2575
|
action = await queue.get()
|
|
2530
|
-
|
|
2531
|
-
|
|
2532
|
-
|
|
2533
|
-
|
|
2534
|
-
|
|
2535
|
-
|
|
2536
|
-
|
|
2537
|
-
|
|
2538
|
-
|
|
2576
|
+
prepared = await asyncio.to_thread(
|
|
2577
|
+
cls._prepare_detail_subscription,
|
|
2578
|
+
generalManagerClass,
|
|
2579
|
+
identification_copy,
|
|
2580
|
+
subscription_user,
|
|
2581
|
+
)
|
|
2582
|
+
if prepared is None:
|
|
2583
|
+
return
|
|
2584
|
+
item, _ = prepared
|
|
2539
2585
|
clear_capability_context(info)
|
|
2540
2586
|
yield SubscriptionEvent(item=item, action=action)
|
|
2541
2587
|
|
{generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/cache/data_change_context.py
RENAMED
|
@@ -162,3 +162,44 @@ def may_reuse_data_change_transaction(database_alias: str) -> bool:
|
|
|
162
162
|
and not owner.caller_in_atomic_block
|
|
163
163
|
and is_data_change_operation_authorized(database_alias)
|
|
164
164
|
)
|
|
165
|
+
|
|
166
|
+
|
|
167
|
+
@dataclass
|
|
168
|
+
class DataChangeOutcome:
|
|
169
|
+
"""Private per-call outcome; unknown/custom mutations remain changes."""
|
|
170
|
+
|
|
171
|
+
interface: object
|
|
172
|
+
unchanged: bool = False
|
|
173
|
+
|
|
174
|
+
|
|
175
|
+
_operation_outcome: ContextVar[DataChangeOutcome | None] = ContextVar(
|
|
176
|
+
"data_change_operation_outcome", default=None
|
|
177
|
+
)
|
|
178
|
+
|
|
179
|
+
|
|
180
|
+
@contextmanager
|
|
181
|
+
def suspend_data_change_outcome() -> Iterator[None]:
|
|
182
|
+
"""Keep nested signal/lifecycle receivers outside their parent's outcome."""
|
|
183
|
+
token = _operation_outcome.set(None)
|
|
184
|
+
try:
|
|
185
|
+
yield
|
|
186
|
+
finally:
|
|
187
|
+
_operation_outcome.reset(token)
|
|
188
|
+
|
|
189
|
+
|
|
190
|
+
@contextmanager
|
|
191
|
+
def capture_data_change_outcome(interface: object) -> Iterator[DataChangeOutcome]:
|
|
192
|
+
"""Isolate the wrapped operation from pre-signals and nested mutations."""
|
|
193
|
+
outcome = DataChangeOutcome(interface)
|
|
194
|
+
token = _operation_outcome.set(outcome)
|
|
195
|
+
try:
|
|
196
|
+
yield outcome
|
|
197
|
+
finally:
|
|
198
|
+
_operation_outcome.reset(token)
|
|
199
|
+
|
|
200
|
+
|
|
201
|
+
def mark_data_change_unchanged(interface: object) -> None:
|
|
202
|
+
"""Accept a proven no-op only for the interface owned by this call."""
|
|
203
|
+
outcome = _operation_outcome.get()
|
|
204
|
+
if outcome is not None and outcome.interface is interface:
|
|
205
|
+
outcome.unchanged = True
|
|
@@ -15,8 +15,10 @@ from django.utils.connection import ConnectionDoesNotExist
|
|
|
15
15
|
from general_manager.cache.data_change_context import (
|
|
16
16
|
DataChangeTransactionScope,
|
|
17
17
|
authorize_data_change_operation,
|
|
18
|
+
capture_data_change_outcome,
|
|
18
19
|
own_data_change_transaction,
|
|
19
20
|
record_data_change_phase,
|
|
21
|
+
suspend_data_change_outcome,
|
|
20
22
|
)
|
|
21
23
|
from general_manager.as_of import reject_historical_mutation
|
|
22
24
|
from general_manager.logging import get_logger
|
|
@@ -66,7 +68,9 @@ def data_change(
|
|
|
66
68
|
clears run-scoped ORM bucket/index caches, emits `pre_data_change`, invokes
|
|
67
69
|
the wrapped callable, then emits `post_data_change` with the changed
|
|
68
70
|
instance, previous instance, action name, identification, and copied
|
|
69
|
-
`_old_values` payload.
|
|
71
|
+
`_old_values` payload. Proven unchanged built-in ORM updates skip only the
|
|
72
|
+
post-change signal; pre-change preparation and transaction cleanup still run.
|
|
73
|
+
Both signals receive a per-call `change_context` and
|
|
70
74
|
the manager interface's database alias. ORM-backed signal dispatch and the
|
|
71
75
|
mutation share one transaction. GraphQL warm-up requeue keys collected
|
|
72
76
|
during signal handling are drained only after the outermost active
|
|
@@ -101,6 +105,7 @@ def data_change(
|
|
|
101
105
|
)
|
|
102
106
|
|
|
103
107
|
@wraps(decorator_source)
|
|
108
|
+
@suspend_data_change_outcome()
|
|
104
109
|
def perform_change(*args: P.args, **kwargs: P.kwargs) -> R:
|
|
105
110
|
"""
|
|
106
111
|
Emit pre_data_change and post_data_change signals around the wrapped function call.
|
|
@@ -252,7 +257,12 @@ def data_change(
|
|
|
252
257
|
if is_orm_backed
|
|
253
258
|
else nullcontext()
|
|
254
259
|
)
|
|
255
|
-
with
|
|
260
|
+
with (
|
|
261
|
+
operation_context,
|
|
262
|
+
capture_data_change_outcome(
|
|
263
|
+
getattr(instance_before, "_interface", None)
|
|
264
|
+
) as outcome,
|
|
265
|
+
):
|
|
256
266
|
mutation_started = (
|
|
257
267
|
perf_counter() if transaction_scope is not None else None
|
|
258
268
|
)
|
|
@@ -282,15 +292,16 @@ def data_change(
|
|
|
282
292
|
if identification is None:
|
|
283
293
|
identification = pre_identification
|
|
284
294
|
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
295
|
+
if not outcome.unchanged:
|
|
296
|
+
post_data_change.send(
|
|
297
|
+
sender=sender,
|
|
298
|
+
instance=instance,
|
|
299
|
+
previous_instance=instance_before,
|
|
300
|
+
identification=identification,
|
|
301
|
+
action=action,
|
|
302
|
+
old_relevant_values=old_relevant_values,
|
|
303
|
+
**signal_kwargs,
|
|
304
|
+
)
|
|
294
305
|
if instance_before is not None:
|
|
295
306
|
try:
|
|
296
307
|
delattr(instance_before, "_old_values")
|
|
@@ -11,7 +11,10 @@ from django.contrib.auth import get_user_model
|
|
|
11
11
|
from django.db import DEFAULT_DB_ALIAS, models, router, transaction
|
|
12
12
|
from django.db.models import NOT_PROVIDED
|
|
13
13
|
|
|
14
|
-
from general_manager.cache.data_change_context import
|
|
14
|
+
from general_manager.cache.data_change_context import (
|
|
15
|
+
mark_data_change_unchanged,
|
|
16
|
+
owns_data_change_transaction,
|
|
17
|
+
)
|
|
15
18
|
from general_manager.interface.capabilities.base import CapabilityName
|
|
16
19
|
from general_manager.interface.capabilities.builtin import BaseCapability
|
|
17
20
|
from general_manager.interface.capabilities.orm_utils.payload_normalizer import (
|
|
@@ -20,6 +23,7 @@ from general_manager.interface.capabilities.orm_utils.payload_normalizer import
|
|
|
20
23
|
from general_manager.interface.capabilities.orm_utils.update_state import (
|
|
21
24
|
changed_many_to_many,
|
|
22
25
|
is_unchanged_update,
|
|
26
|
+
record_skipped_update_save,
|
|
23
27
|
track_update,
|
|
24
28
|
)
|
|
25
29
|
from general_manager.interface.utils.database_interface_protocols import (
|
|
@@ -225,6 +229,7 @@ class OrmMutationCapability(BaseCapability):
|
|
|
225
229
|
object.__setattr__(instance, "changed_by_id", creator_id)
|
|
226
230
|
instance.full_clean()
|
|
227
231
|
if is_unchanged_update(instance):
|
|
232
|
+
record_skipped_update_save(instance)
|
|
228
233
|
return instance.pk
|
|
229
234
|
if batch is not None and database_alias is None:
|
|
230
235
|
if (
|
|
@@ -606,7 +611,7 @@ class OrmUpdateCapability(BaseCapability):
|
|
|
606
611
|
changed_many,
|
|
607
612
|
history_comment,
|
|
608
613
|
database_alias=database_alias,
|
|
609
|
-
):
|
|
614
|
+
) as update_state:
|
|
610
615
|
instance = mutation.assign_simple_attributes(
|
|
611
616
|
interface_instance.__class__, instance, normalized_simple
|
|
612
617
|
)
|
|
@@ -624,6 +629,32 @@ class OrmUpdateCapability(BaseCapability):
|
|
|
624
629
|
history_comment=history_comment,
|
|
625
630
|
)
|
|
626
631
|
discard_orm_instance_cache(interface_instance.__class__, pk)
|
|
632
|
+
if update_state is not None and update_state.save_skipped:
|
|
633
|
+
# A custom wrapper may write after delegating to a built-in
|
|
634
|
+
# method. Only the complete standard path can prove a no-op.
|
|
635
|
+
from general_manager.interface.base_interface import InterfaceBase
|
|
636
|
+
|
|
637
|
+
standard_methods = (
|
|
638
|
+
(interface_instance.update, InterfaceBase.update),
|
|
639
|
+
(self.update, OrmUpdateCapability.update),
|
|
640
|
+
(
|
|
641
|
+
mutation.assign_simple_attributes,
|
|
642
|
+
OrmMutationCapability.assign_simple_attributes,
|
|
643
|
+
),
|
|
644
|
+
(
|
|
645
|
+
mutation.save_with_history,
|
|
646
|
+
OrmMutationCapability.save_with_history,
|
|
647
|
+
),
|
|
648
|
+
(
|
|
649
|
+
mutation.apply_many_to_many,
|
|
650
|
+
OrmMutationCapability.apply_many_to_many,
|
|
651
|
+
),
|
|
652
|
+
)
|
|
653
|
+
if all(
|
|
654
|
+
getattr(method, "__func__", None) is standard
|
|
655
|
+
for method, standard in standard_methods
|
|
656
|
+
):
|
|
657
|
+
mark_data_change_unchanged(interface_instance)
|
|
627
658
|
return {"id": pk}
|
|
628
659
|
|
|
629
660
|
return call_with_observability(
|
|
@@ -16,10 +16,11 @@ from django.db.models.fields.files import FieldFile
|
|
|
16
16
|
from general_manager.measurement.measurement_field import MeasurementField
|
|
17
17
|
|
|
18
18
|
|
|
19
|
-
@dataclass
|
|
19
|
+
@dataclass
|
|
20
20
|
class _UpdateState:
|
|
21
21
|
instance: models.Model
|
|
22
22
|
values: dict[str, object]
|
|
23
|
+
save_skipped: bool = False
|
|
23
24
|
|
|
24
25
|
|
|
25
26
|
_update_state: ContextVar[_UpdateState | None] = ContextVar(
|
|
@@ -47,7 +48,7 @@ def track_update(
|
|
|
47
48
|
history_comment: str | None,
|
|
48
49
|
*,
|
|
49
50
|
database_alias: str | None = None,
|
|
50
|
-
) -> Iterator[None]:
|
|
51
|
+
) -> Iterator[_UpdateState | None]:
|
|
51
52
|
"""Scope the original row to its save, including nested mutation calls.
|
|
52
53
|
|
|
53
54
|
The save compares after full_clean(), so validation and changes made by
|
|
@@ -85,7 +86,7 @@ def track_update(
|
|
|
85
86
|
state = _UpdateState(instance, values)
|
|
86
87
|
token = _update_state.set(state)
|
|
87
88
|
try:
|
|
88
|
-
yield
|
|
89
|
+
yield state
|
|
89
90
|
finally:
|
|
90
91
|
_update_state.reset(token)
|
|
91
92
|
|
|
@@ -107,6 +108,13 @@ def is_unchanged_update(instance: models.Model) -> bool:
|
|
|
107
108
|
return True
|
|
108
109
|
|
|
109
110
|
|
|
111
|
+
def record_skipped_update_save(instance: models.Model) -> None:
|
|
112
|
+
"""Record the built-in save decision without classifying custom wrappers."""
|
|
113
|
+
state = _update_state.get()
|
|
114
|
+
if state is not None and state.instance is instance:
|
|
115
|
+
state.save_skipped = True
|
|
116
|
+
|
|
117
|
+
|
|
110
118
|
def changed_many_to_many(
|
|
111
119
|
instance: models.Model,
|
|
112
120
|
values: dict[str, list[object]],
|
{generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/workflow/signal_bridge.py
RENAMED
|
@@ -29,6 +29,8 @@ _WORKFLOW_SIGNAL_BRIDGE_KEY = "WORKFLOW_SIGNAL_BRIDGE"
|
|
|
29
29
|
_DISPATCH_UID = "general_manager_workflow_signal_bridge"
|
|
30
30
|
|
|
31
31
|
_RESERVED_KEYS = {
|
|
32
|
+
"change_context",
|
|
33
|
+
"database_alias",
|
|
32
34
|
"creator_id",
|
|
33
35
|
"history_comment",
|
|
34
36
|
"identification",
|
|
@@ -88,8 +90,8 @@ def _manager_change_to_event(
|
|
|
88
90
|
for key, value in kwargs.items()
|
|
89
91
|
if key not in _RESERVED_KEYS and not key.startswith("_")
|
|
90
92
|
}
|
|
91
|
-
|
|
92
|
-
|
|
93
|
+
# The mutation outcome controls no-op suppression. Empty input can still
|
|
94
|
+
# create defaults, change values in clean(), or request an audit touch.
|
|
93
95
|
|
|
94
96
|
identification = kwargs.get("identification")
|
|
95
97
|
if identification is None:
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{generalmanager-0.86.0 → generalmanager-0.86.2}/src/GeneralManager.egg-info/dependency_links.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/_types/general_manager.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/api/graphql_identifiers.py
RENAMED
|
File without changes
|
{generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/api/graphql_mutations.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/api/graphql_relations.py
RENAMED
|
File without changes
|
{generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/api/graphql_resolvers.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/api/graphql_subscriptions.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/api/graphql_warmup_registry.py
RENAMED
|
File without changes
|
{generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/api/graphql_warmup_tasks.py
RENAMED
|
File without changes
|
|
File without changes
|
{generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/api/notification_batching.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/api/remote_invalidation.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/bucket/_materialized_bucket.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/bucket/calculation_bucket.py
RENAMED
|
File without changes
|
{generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/bucket/database_bucket.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/bucket/request_bucket.py
RENAMED
|
File without changes
|
|
File without changes
|
{generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/cache/_dependency_graph.py
RENAMED
|
File without changes
|
|
File without changes
|
{generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/cache/cache_decorator.py
RENAMED
|
File without changes
|
|
File without changes
|
{generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/cache/dependency_cache.py
RENAMED
|
File without changes
|
{generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/cache/dependency_index.py
RENAMED
|
File without changes
|
{generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/cache/dependency_matching.py
RENAMED
|
File without changes
|
{generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/cache/dependency_publish.py
RENAMED
|
File without changes
|
{generalmanager-0.86.0 → generalmanager-0.86.2}/src/general_manager/cache/dependency_shards.py
RENAMED
|
File without changes
|