GeneralManager 0.87.2__tar.gz → 0.87.3__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.87.2/src/GeneralManager.egg-info → generalmanager-0.87.3}/PKG-INFO +1 -1
- {generalmanager-0.87.2 → generalmanager-0.87.3}/pyproject.toml +1 -1
- {generalmanager-0.87.2 → generalmanager-0.87.3/src/GeneralManager.egg-info}/PKG-INFO +1 -1
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/GeneralManager.egg-info/SOURCES.txt +1 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/api/property.py +12 -9
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/as_of.py +60 -3
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/cache/signals.py +1 -1
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/interface/base_interface.py +6 -4
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/interface/capabilities/orm/history.py +30 -10
- generalmanager-0.87.3/src/general_manager/interface/capabilities/orm/history_query.py +178 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/interface/capabilities/orm/support.py +3 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/interface/capabilities/orm_utils/field_descriptors.py +23 -3
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/manager/general_manager.py +8 -3
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/manager/meta.py +136 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/LICENSE +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/README.md +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/setup.cfg +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/GeneralManager.egg-info/dependency_links.txt +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/GeneralManager.egg-info/requires.txt +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/GeneralManager.egg-info/top_level.txt +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/__init__.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/_types/__init__.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/_types/api.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/_types/bucket.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/_types/cache.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/_types/dataframes.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/_types/factory.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/_types/general_manager.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/_types/interface.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/_types/manager.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/_types/measurement.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/_types/permission.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/_types/rule.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/_types/search.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/_types/utils.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/api/__init__.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/api/graphql.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/api/graphql_as_of.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/api/graphql_errors.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/api/graphql_filter_contract.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/api/graphql_groups.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/api/graphql_identifiers.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/api/graphql_mutations.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/api/graphql_ordering.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/api/graphql_output.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/api/graphql_prefetch.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/api/graphql_query_permissions.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/api/graphql_relations.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/api/graphql_resolvers.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/api/graphql_search.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/api/graphql_subscription_consumer.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/api/graphql_subscriptions.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/api/graphql_type.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/api/graphql_units.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/api/graphql_value_contract.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/api/graphql_view.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/api/graphql_warmup.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/api/graphql_warmup_registry.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/api/graphql_warmup_tasks.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/api/mutation.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/api/mutation_controls.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/api/notification_batching.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/api/registry.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/api/remote_api.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/api/remote_invalidation.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/api/remote_invalidation_client.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/apps.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/bootstrap.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/bucket/__init__.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/bucket/_materialized_bucket.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/bucket/_ordering.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/bucket/base_bucket.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/bucket/calculation_bucket.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/bucket/database_bucket.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/bucket/excel_bucket.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/bucket/group_bucket.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/bucket/indexing.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/bucket/projection.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/bucket/request_bucket.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/cache/__init__.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/cache/_dependency_graph.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/cache/batch_refresh.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/cache/cache_decorator.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/cache/cache_tracker.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/cache/data_change_context.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/cache/dependency_cache.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/cache/dependency_index.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/cache/dependency_matching.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/cache/dependency_publish.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/cache/dependency_shards.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/cache/model_dependency_collector.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/cache/run_context.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/cache/run_context_lru.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/cache/transaction_barrier.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/chat/__init__.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/chat/audit.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/chat/audit_identity.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/chat/bootstrap.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/chat/checks.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/chat/consumer.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/chat/context.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/chat/errors.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/chat/evals/__init__.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/chat/evals/__main__.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/chat/evals/baseline.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/chat/evals/datasets/basic_queries.yaml +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/chat/evals/datasets/demo_readiness.yaml +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/chat/evals/datasets/edge_cases.yaml +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/chat/evals/datasets/follow_ups.yaml +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/chat/evals/datasets/large_schema.yaml +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/chat/evals/datasets/multi_hop.yaml +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/chat/evals/datasets/planned_orchestration.yaml +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/chat/evals/diagnostics.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/chat/evals/execution.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/chat/evals/fingerprints.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/chat/evals/fixtures.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/chat/evals/judges/__init__.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/chat/evals/judges/answer_quality.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/chat/evals/judges/contract.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/chat/evals/judges/result_accuracy.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/chat/evals/judges/result_set.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/chat/evals/judges/tool_sequence.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/chat/evals/outcomes.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/chat/evals/readiness.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/chat/evals/runner.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/chat/evals/traces.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/chat/graphql_contract.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/chat/grounding.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/chat/models.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/chat/mutation_inputs.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/chat/planned/__init__.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/chat/planned/action_contract.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/chat/planned/binding_diagnostics.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/chat/planned/budget.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/chat/planned/calculation_scope.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/chat/planned/calculations.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/chat/planned/catalog.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/chat/planned/category_binding.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/chat/planned/choice_context.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/chat/planned/clarification.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/chat/planned/config.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/chat/planned/contract.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/chat/planned/conversion.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/chat/planned/cross_query.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/chat/planned/deferred_calculations.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/chat/planned/deferred_schema.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/chat/planned/events.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/chat/planned/evidence.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/chat/planned/evidence_selection.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/chat/planned/group_actions.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/chat/planned/models.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/chat/planned/planner.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/chat/planned/planner_context.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/chat/planned/provider_calls.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/chat/planned/resolver.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/chat/planned/scheduler.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/chat/planned/schema_projection.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/chat/planned/selector_clarification.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/chat/planned/selector_question.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/chat/planned/synthesis.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/chat/planned/validation.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/chat/providers/__init__.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/chat/providers/_shared.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/chat/providers/anthropic.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/chat/providers/base.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/chat/providers/google.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/chat/providers/ollama.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/chat/providers/openai.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/chat/rate_limits.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/chat/routing.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/chat/schema_index.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/chat/schema_inspection.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/chat/settings.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/chat/signals.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/chat/system_prompt.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/chat/tool_metadata.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/chat/tools.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/chat/turns.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/chat/views.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/conf.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/dataframes/__init__.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/dataframes/measurements.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/factory/__init__.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/factory/auto_factory.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/factory/factories.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/factory/factory_methods.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/interface/__init__.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/interface/bundles/__init__.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/interface/bundles/calculation.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/interface/bundles/database.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/interface/bundles/excel.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/interface/bundles/remote_manager.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/interface/bundles/request.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/interface/capabilities/__init__.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/interface/capabilities/base.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/interface/capabilities/builtin.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/interface/capabilities/calculation/__init__.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/interface/capabilities/calculation/_compat.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/interface/capabilities/calculation/input_resolution.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/interface/capabilities/calculation/lifecycle.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/interface/capabilities/configuration.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/interface/capabilities/core/observability.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/interface/capabilities/core/utils.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/interface/capabilities/excel/__init__.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/interface/capabilities/exceptions.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/interface/capabilities/existing_model/__init__.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/interface/capabilities/existing_model/_compat.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/interface/capabilities/existing_model/resolution.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/interface/capabilities/factory.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/interface/capabilities/orm/__init__.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/interface/capabilities/orm/_compat.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/interface/capabilities/orm/bulk.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/interface/capabilities/orm/create_many.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/interface/capabilities/orm/lifecycle.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/interface/capabilities/orm/mutations.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/interface/capabilities/orm_utils/__init__.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/interface/capabilities/orm_utils/django_manager_utils.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/interface/capabilities/orm_utils/payload_normalizer.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/interface/capabilities/orm_utils/update_state.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/interface/capabilities/read_only/__init__.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/interface/capabilities/read_only/_compat.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/interface/capabilities/read_only/_types.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/interface/capabilities/read_only/lifecycle.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/interface/capabilities/read_only/management.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/interface/capabilities/registry.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/interface/capabilities/remote_manager.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/interface/capabilities/request/__init__.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/interface/excel.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/interface/excel_store.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/interface/excel_workbook.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/interface/infrastructure/__init__.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/interface/infrastructure/startup_hooks.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/interface/infrastructure/system_checks.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/interface/interfaces/__init__.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/interface/interfaces/calculation.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/interface/interfaces/database.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/interface/interfaces/excel.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/interface/interfaces/existing_model.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/interface/interfaces/read_only.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/interface/interfaces/remote_manager.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/interface/interfaces/request.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/interface/manifests/__init__.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/interface/manifests/capability_builder.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/interface/manifests/capability_manifest.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/interface/manifests/capability_models.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/interface/orm_interface.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/interface/requests.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/interface/unit_contract.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/interface/utils/__init__.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/interface/utils/database_interface_protocols.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/interface/utils/errors.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/interface/utils/history.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/interface/utils/models.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/logging.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/management/commands/chat_cleanup.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/management/commands/cleanup_upload_intents.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/management/commands/graphql_warmup.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/management/commands/graphql_warmup_refresh_due.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/management/commands/search_index.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/management/commands/search_reconcile.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/management/commands/seed_manager_landscape.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/management/commands/shell.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/management/commands/sync_read_only.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/management/commands/workflow_drain_outbox.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/management/commands/workflow_replay_dead_letters.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/manager/__init__.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/manager/bulk_create.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/manager/group_manager.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/manager/input.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/measurement/__init__.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/measurement/measurement.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/measurement/measurement_field.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/metrics/__init__.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/metrics/graphql.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/migrations/0001_initial.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/migrations/0002_workflow_outbox_scaling_indexes.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/migrations/0003_workflow_execution_correlation_constraint.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/migrations/0004_chat_persistence_models.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/migrations/0004_search_index_state.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/migrations/0005_merge_chat_search.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/migrations/0006_chat_pending_confirmation_scoped_ids.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/migrations/0007_upload_intent.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/migrations/0008_upload_finalization_versions.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/migrations/0009_upload_cleanup_state.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/migrations/0010_chat_pending_confirmation_portable_uniqueness.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/migrations/0011_search_index_state_dirty_generation.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/migrations/0012_chat_context_watermarks.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/migrations/__init__.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/models.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/permission/__init__.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/permission/audit.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/permission/base_permission.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/permission/graphql_capabilities.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/permission/manager_based_permission.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/permission/mutation_permission.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/permission/permission_checks.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/permission/permission_data_manager.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/permission/utils.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/public_api_registry.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/py.typed +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/rule/__init__.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/rule/handler.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/rule/rule.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/search/__init__.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/search/async_tasks.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/search/backend.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/search/backend_registry.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/search/backends/__init__.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/search/backends/dev.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/search/backends/meilisearch.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/search/backends/opensearch.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/search/backends/typesense.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/search/checks.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/search/config.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/search/identity.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/search/indexer.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/search/invalidation.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/search/m2m_invalidation.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/search/models.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/search/reconciliation.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/search/registry.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/search/tasks.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/search/utils.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/seeding/__init__.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/seeding/manager_landscape.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/uploads/__init__.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/uploads/adapters.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/uploads/checks.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/uploads/config.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/uploads/errors.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/uploads/finalization.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/uploads/graphql.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/uploads/graphql_types.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/uploads/metrics.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/uploads/models.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/uploads/public.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/uploads/s3.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/uploads/services.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/uploads/tokens.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/uploads/types.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/uploads/urls.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/uploads/views.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/utils/__init__.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/utils/_args_to_kwargs.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/utils/_cache_key_encoder.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/utils/_make_cache_key.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/utils/_none_to_zero.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/utils/executable_contract.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/utils/filter_parser.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/utils/format_string.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/utils/json_encoder.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/utils/path_mapping.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/utils/public_api.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/utils/testing.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/utils/type_checks.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/workflow/__init__.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/workflow/actions.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/workflow/backend_registry.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/workflow/backends/__init__.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/workflow/backends/celery.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/workflow/backends/local.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/workflow/backends/n8n.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/workflow/config.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/workflow/engine.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/workflow/event_registry.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/workflow/events.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/workflow/models.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/workflow/signal_bridge.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/workflow/tasks.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/workflow/telemetry.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/tests/test_settings.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/tests/test_urls.py +0 -0
- {generalmanager-0.87.2 → generalmanager-0.87.3}/tests/testing_asgi.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: GeneralManager
|
|
3
|
-
Version: 0.87.
|
|
3
|
+
Version: 0.87.3
|
|
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.87.
|
|
7
|
+
version = "0.87.3"
|
|
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.87.
|
|
3
|
+
Version: 0.87.3
|
|
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
|
|
@@ -216,6 +216,7 @@ src/general_manager/interface/capabilities/orm/_compat.py
|
|
|
216
216
|
src/general_manager/interface/capabilities/orm/bulk.py
|
|
217
217
|
src/general_manager/interface/capabilities/orm/create_many.py
|
|
218
218
|
src/general_manager/interface/capabilities/orm/history.py
|
|
219
|
+
src/general_manager/interface/capabilities/orm/history_query.py
|
|
219
220
|
src/general_manager/interface/capabilities/orm/lifecycle.py
|
|
220
221
|
src/general_manager/interface/capabilities/orm/mutations.py
|
|
221
222
|
src/general_manager/interface/capabilities/orm/support.py
|
|
@@ -11,6 +11,12 @@ from functools import wraps
|
|
|
11
11
|
import sys
|
|
12
12
|
from typing import Callable, Literal, TypeVar, cast, get_type_hints, overload
|
|
13
13
|
|
|
14
|
+
from general_manager.as_of import (
|
|
15
|
+
_bind_property_result,
|
|
16
|
+
_ensure_property_supported,
|
|
17
|
+
_property_as_of,
|
|
18
|
+
)
|
|
19
|
+
|
|
14
20
|
T = TypeVar("T", bound=Callable[..., object])
|
|
15
21
|
GraphQLPropertyCache = Literal["dependency", "run", "timeout", "none"]
|
|
16
22
|
_TYPE_HINT_UNRESOLVED = object()
|
|
@@ -148,15 +154,12 @@ class GraphQLProperty(property):
|
|
|
148
154
|
@wraps(fget)
|
|
149
155
|
def resolver(instance: object) -> object:
|
|
150
156
|
"""Resolve the property through the selected cached wrapper."""
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
if cached_fget is None:
|
|
158
|
-
cached_fget = self._get_cached_fget()
|
|
159
|
-
return cached_fget(instance)
|
|
157
|
+
with _property_as_of(instance) as snapshot:
|
|
158
|
+
_ensure_property_supported(self._raw_fget, snapshot)
|
|
159
|
+
cached_fget = self._cached_fget
|
|
160
|
+
if cached_fget is None:
|
|
161
|
+
cached_fget = self._get_cached_fget()
|
|
162
|
+
return _bind_property_result(cached_fget(instance), snapshot)
|
|
160
163
|
|
|
161
164
|
super().__init__(resolver, doc=doc)
|
|
162
165
|
self.is_graphql_resolver = True
|
|
@@ -2,10 +2,18 @@
|
|
|
2
2
|
|
|
3
3
|
from __future__ import annotations
|
|
4
4
|
|
|
5
|
-
from collections.abc import
|
|
5
|
+
from collections.abc import (
|
|
6
|
+
AsyncIterator,
|
|
7
|
+
Awaitable,
|
|
8
|
+
Callable,
|
|
9
|
+
Iterator,
|
|
10
|
+
Mapping,
|
|
11
|
+
)
|
|
6
12
|
from contextlib import contextmanager
|
|
7
13
|
from contextvars import ContextVar
|
|
8
14
|
from datetime import UTC, date, datetime, time
|
|
15
|
+
from inspect import isasyncgenfunction, isawaitable, isgeneratorfunction, unwrap
|
|
16
|
+
from typing import cast
|
|
9
17
|
|
|
10
18
|
from django.utils import timezone
|
|
11
19
|
|
|
@@ -94,11 +102,16 @@ def as_of_cache_fingerprint() -> str | None:
|
|
|
94
102
|
return None if active is None else search_date_cache_fingerprint(active)
|
|
95
103
|
|
|
96
104
|
|
|
97
|
-
def reject_historical_mutation() -> None:
|
|
98
|
-
"""Reject mutations
|
|
105
|
+
def reject_historical_mutation(bound: object | None = None) -> None:
|
|
106
|
+
"""Reject mutations in a historical operation or through a dated object."""
|
|
99
107
|
active = current_as_of_date()
|
|
100
108
|
if active is not None:
|
|
101
109
|
raise HistoricalMutationError(active)
|
|
110
|
+
state = getattr(bound, "__dict__", None)
|
|
111
|
+
if isinstance(state, Mapping):
|
|
112
|
+
snapshot = state.get("_effective_search_date", state.get("_search_date"))
|
|
113
|
+
if isinstance(snapshot, datetime):
|
|
114
|
+
raise HistoricalMutationError(snapshot)
|
|
102
115
|
|
|
103
116
|
|
|
104
117
|
def ensure_as_of_read_supported(interface_cls: type[object]) -> None:
|
|
@@ -128,6 +141,50 @@ def resolve_search_date(explicit: SearchDateInput | None) -> datetime | None:
|
|
|
128
141
|
return normalized
|
|
129
142
|
|
|
130
143
|
|
|
144
|
+
@contextmanager
|
|
145
|
+
def _property_as_of(instance: object) -> Iterator[datetime | None]:
|
|
146
|
+
"""Evaluate a manager property and its cache under the bound snapshot."""
|
|
147
|
+
ensure = getattr(instance, "_ensure_as_of_compatible", None)
|
|
148
|
+
if callable(ensure):
|
|
149
|
+
ensure()
|
|
150
|
+
state = getattr(instance, "__dict__", {})
|
|
151
|
+
snapshot = state.get("_effective_search_date")
|
|
152
|
+
if isinstance(snapshot, datetime):
|
|
153
|
+
with as_of(snapshot):
|
|
154
|
+
yield snapshot
|
|
155
|
+
else:
|
|
156
|
+
yield current_as_of_date()
|
|
157
|
+
|
|
158
|
+
|
|
159
|
+
def _bind_property_result(value: object, snapshot: datetime | None) -> object:
|
|
160
|
+
"""Bind awaitables and reject iterator bodies that can escape the scope."""
|
|
161
|
+
if snapshot is None:
|
|
162
|
+
return value
|
|
163
|
+
if isinstance(value, (Iterator, AsyncIterator)):
|
|
164
|
+
close = getattr(value, "close", None)
|
|
165
|
+
if callable(close):
|
|
166
|
+
close()
|
|
167
|
+
raise HistoricalReadNotSupportedError()
|
|
168
|
+
if isawaitable(value):
|
|
169
|
+
return _await_as_of(cast(Awaitable[object], value), snapshot)
|
|
170
|
+
return value
|
|
171
|
+
|
|
172
|
+
|
|
173
|
+
def _ensure_property_supported(
|
|
174
|
+
getter: Callable[..., object], snapshot: datetime | None
|
|
175
|
+
) -> None:
|
|
176
|
+
"""Reject generator properties before constructing deferred bodies."""
|
|
177
|
+
if snapshot is not None and (
|
|
178
|
+
isgeneratorfunction(unwrap(getter)) or isasyncgenfunction(unwrap(getter))
|
|
179
|
+
):
|
|
180
|
+
raise HistoricalReadNotSupportedError()
|
|
181
|
+
|
|
182
|
+
|
|
183
|
+
async def _await_as_of(value: Awaitable[object], snapshot: datetime) -> object:
|
|
184
|
+
with as_of(snapshot):
|
|
185
|
+
return _bind_property_result(await value, snapshot)
|
|
186
|
+
|
|
187
|
+
|
|
131
188
|
@contextmanager
|
|
132
189
|
def as_of(search_date: SearchDateInput) -> Iterator[datetime]:
|
|
133
190
|
"""Run an operation with a normalized historical date."""
|
|
@@ -119,7 +119,7 @@ def data_change(
|
|
|
119
119
|
Returns:
|
|
120
120
|
R: The result returned by the wrapped function.
|
|
121
121
|
"""
|
|
122
|
-
reject_historical_mutation()
|
|
122
|
+
reject_historical_mutation(args[0] if args else None)
|
|
123
123
|
|
|
124
124
|
from general_manager.cache.dependency_index import (
|
|
125
125
|
begin_dependency_data_change,
|
{generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/interface/base_interface.py
RENAMED
|
@@ -105,7 +105,8 @@ def _guard_mutation_callable(
|
|
|
105
105
|
|
|
106
106
|
@wraps(mutation)
|
|
107
107
|
async def async_guarded(*args: object, **kwargs: object) -> object:
|
|
108
|
-
|
|
108
|
+
"""Reject historical writes before invoking the async mutation."""
|
|
109
|
+
reject_historical_mutation(args[0] if args else None)
|
|
109
110
|
awaitable = cast(Awaitable[object], mutation(*args, **kwargs))
|
|
110
111
|
return await awaitable
|
|
111
112
|
|
|
@@ -114,7 +115,8 @@ def _guard_mutation_callable(
|
|
|
114
115
|
|
|
115
116
|
@wraps(mutation)
|
|
116
117
|
def sync_guarded(*args: object, **kwargs: object) -> object:
|
|
117
|
-
|
|
118
|
+
"""Reject historical writes before invoking the synchronous mutation."""
|
|
119
|
+
reject_historical_mutation(args[0] if args else None)
|
|
118
120
|
return mutation(*args, **kwargs)
|
|
119
121
|
|
|
120
122
|
setattr(sync_guarded, _HISTORICAL_MUTATION_GUARD_MARKER, True)
|
|
@@ -1266,7 +1268,7 @@ class InterfaceBase(ABC):
|
|
|
1266
1268
|
Raises:
|
|
1267
1269
|
NotImplementedError: If this interface does not provide an update capability.
|
|
1268
1270
|
"""
|
|
1269
|
-
reject_historical_mutation()
|
|
1271
|
+
reject_historical_mutation(self)
|
|
1270
1272
|
observer = self.get_capability_handler("observability")
|
|
1271
1273
|
|
|
1272
1274
|
def _invoke() -> object:
|
|
@@ -1311,7 +1313,7 @@ class InterfaceBase(ABC):
|
|
|
1311
1313
|
Raises:
|
|
1312
1314
|
NotImplementedError: If the interface does not provide a delete capability.
|
|
1313
1315
|
"""
|
|
1314
|
-
reject_historical_mutation()
|
|
1316
|
+
reject_historical_mutation(self)
|
|
1315
1317
|
observer = self.get_capability_handler("observability")
|
|
1316
1318
|
|
|
1317
1319
|
def _invoke() -> object:
|
|
@@ -16,9 +16,11 @@ from general_manager.interface.utils.database_interface_protocols import (
|
|
|
16
16
|
)
|
|
17
17
|
|
|
18
18
|
from .support import get_support_capability
|
|
19
|
+
from .history_query import ManagerHistoryQuery
|
|
19
20
|
|
|
20
21
|
if TYPE_CHECKING: # pragma: no cover
|
|
21
22
|
from general_manager.interface.orm_interface import OrmInterfaceBase
|
|
23
|
+
from general_manager.manager.general_manager import GeneralManager
|
|
22
24
|
|
|
23
25
|
|
|
24
26
|
class HistoryNotSupportedError(RuntimeError):
|
|
@@ -175,6 +177,8 @@ class OrmHistoryCapability(BaseCapability):
|
|
|
175
177
|
pk_filter: dict[str, object] | None
|
|
176
178
|
if isinstance(instance, SupportsHistory):
|
|
177
179
|
history_manager = instance.history
|
|
180
|
+
if isinstance(history_manager, ManagerHistoryQuery):
|
|
181
|
+
history_manager = cast(SupportsHistoryQuery, history_manager.raw)
|
|
178
182
|
pk_filter = self._get_instance_pk_filter(instance)
|
|
179
183
|
else:
|
|
180
184
|
pk_filter = self._get_model_pk_filter(interface_cls, instance)
|
|
@@ -198,36 +202,52 @@ class OrmHistoryCapability(BaseCapability):
|
|
|
198
202
|
self,
|
|
199
203
|
interface_cls: type["OrmInterfaceBase[models.Model]"],
|
|
200
204
|
manager: object,
|
|
201
|
-
) ->
|
|
205
|
+
) -> ManagerHistoryQuery[GeneralManager]:
|
|
202
206
|
"""
|
|
203
|
-
Return
|
|
207
|
+
Return manager-valued history scoped to the original object's key.
|
|
204
208
|
|
|
205
|
-
The target identifier
|
|
206
|
-
``manager.
|
|
209
|
+
The target identifier prefers mapping-like ``manager.identification["id"]``,
|
|
210
|
+
then falls back to ``manager.pk`` or ``manager.id``. The
|
|
207
211
|
lookup key defaults to ``"id"`` and uses the interface model primary-key
|
|
208
212
|
field name when it is available as a string. A configured database alias
|
|
209
|
-
is applied before the
|
|
213
|
+
is applied before the query is wrapped. Object results are the original
|
|
214
|
+
manager class at a fixed snapshot; ``.raw`` retains audit rows.
|
|
210
215
|
|
|
211
216
|
Parameters:
|
|
212
217
|
interface_cls: ORM interface whose underlying model provides the history manager.
|
|
213
218
|
manager: Manager-like object exposing ``pk``, ``id``, or ``identification["id"]`` for the target row.
|
|
214
219
|
|
|
215
220
|
Returns:
|
|
216
|
-
|
|
221
|
+
Manager-valued history with raw audit access for the target object.
|
|
217
222
|
|
|
218
223
|
Raises:
|
|
219
224
|
HistoryNotSupportedError: If the interface does not expose a history manager or the manager cannot be scoped to a primary key.
|
|
220
225
|
"""
|
|
221
226
|
if not hasattr(interface_cls._model, "history"):
|
|
222
227
|
raise HistoryNotSupportedError(interface_cls.__name__)
|
|
223
|
-
|
|
228
|
+
from general_manager.manager.general_manager import GeneralManager
|
|
229
|
+
|
|
230
|
+
identification = getattr(manager, "identification", None)
|
|
231
|
+
pk_filter: dict[str, object] | None
|
|
232
|
+
if isinstance(identification, Mapping) and identification.get("id") is not None:
|
|
233
|
+
pk_field = interface_cls._model._meta.pk
|
|
234
|
+
pk_filter = {pk_field.name if pk_field else "id": identification["id"]}
|
|
235
|
+
else:
|
|
236
|
+
pk_filter = self._get_model_pk_filter(interface_cls, manager)
|
|
224
237
|
if pk_filter is None:
|
|
225
238
|
raise HistoryNotSupportedError(interface_cls.__name__)
|
|
226
239
|
history_manager = cast(SupportsHistory, interface_cls._model).history
|
|
227
240
|
history_manager = self._apply_database_alias(interface_cls, history_manager)
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
241
|
+
manager_class = (
|
|
242
|
+
type(manager)
|
|
243
|
+
if isinstance(manager, GeneralManager)
|
|
244
|
+
else interface_cls._parent_class
|
|
245
|
+
)
|
|
246
|
+
snapshot = getattr(manager, "_effective_search_date", None)
|
|
247
|
+
return ManagerHistoryQuery(
|
|
248
|
+
cast(models.QuerySet[models.Model], history_manager.filter(**pk_filter)),
|
|
249
|
+
manager_class,
|
|
250
|
+
search_date=snapshot if isinstance(snapshot, datetime) else None,
|
|
231
251
|
)
|
|
232
252
|
|
|
233
253
|
def get_historical_queryset(
|
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
"""Manager-valued selection over an object's raw audit history."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from collections.abc import Iterator
|
|
6
|
+
from datetime import UTC, datetime, timedelta
|
|
7
|
+
from typing import TYPE_CHECKING, Any, Generic, TypeVar, cast, overload
|
|
8
|
+
|
|
9
|
+
from django.db import models
|
|
10
|
+
from django.utils import timezone
|
|
11
|
+
|
|
12
|
+
from general_manager.as_of import (
|
|
13
|
+
HistoricalContextConflictError,
|
|
14
|
+
as_of,
|
|
15
|
+
resolve_search_date,
|
|
16
|
+
)
|
|
17
|
+
|
|
18
|
+
if TYPE_CHECKING:
|
|
19
|
+
from general_manager.manager.general_manager import GeneralManager
|
|
20
|
+
|
|
21
|
+
ManagerT = TypeVar("ManagerT", bound="GeneralManager")
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
class ManagerHistoryQuery(Generic[ManagerT]):
|
|
25
|
+
"""Select original managers while retaining explicit raw audit access.
|
|
26
|
+
|
|
27
|
+
Query shaping and scalar projections use Django's history queryset. Object
|
|
28
|
+
selection binds each version to its closing snapshot, or to the exact
|
|
29
|
+
explicit/ambient date. ``raw`` is the unchanged audit queryset, including
|
|
30
|
+
tombstones and zero-duration versions, and is intentionally not a dated
|
|
31
|
+
entity read. Less common Django audit operations belong on that queryset.
|
|
32
|
+
"""
|
|
33
|
+
|
|
34
|
+
def __init__(
|
|
35
|
+
self,
|
|
36
|
+
raw: models.QuerySet[models.Model],
|
|
37
|
+
manager_class: type[ManagerT],
|
|
38
|
+
*,
|
|
39
|
+
search_date: datetime | None = None,
|
|
40
|
+
timeline: models.QuerySet[models.Model] | None = None,
|
|
41
|
+
) -> None:
|
|
42
|
+
"""Capture the query's date and keep its unfiltered entity timeline."""
|
|
43
|
+
self.raw = raw
|
|
44
|
+
self._manager_class = manager_class
|
|
45
|
+
self._search_date = resolve_search_date(search_date)
|
|
46
|
+
self._timeline = raw if timeline is None else timeline
|
|
47
|
+
|
|
48
|
+
def _clone(
|
|
49
|
+
self, raw: models.QuerySet[models.Model]
|
|
50
|
+
) -> ManagerHistoryQuery[ManagerT]:
|
|
51
|
+
return type(self)(
|
|
52
|
+
raw,
|
|
53
|
+
self._manager_class,
|
|
54
|
+
search_date=self._search_date,
|
|
55
|
+
timeline=self._timeline,
|
|
56
|
+
)
|
|
57
|
+
|
|
58
|
+
def _dated_query(self) -> models.QuerySet[models.Model]:
|
|
59
|
+
"""Limit candidate audit rows to the resolved explicit or ambient date."""
|
|
60
|
+
snapshot = resolve_search_date(self._search_date)
|
|
61
|
+
if snapshot is None:
|
|
62
|
+
return self.raw
|
|
63
|
+
return self.raw.filter(history_date__lte=snapshot)
|
|
64
|
+
|
|
65
|
+
def _materialize(self, row: models.Model) -> ManagerT:
|
|
66
|
+
"""Resolve a real version interval and construct under its snapshot.
|
|
67
|
+
|
|
68
|
+
Tombstones are audit-only. A datetime cannot select a zero-duration
|
|
69
|
+
interval, and an explicit date must fall inside the selected version.
|
|
70
|
+
"""
|
|
71
|
+
audit = cast(Any, row)
|
|
72
|
+
model = cast(Any, self._manager_class.Interface)._model
|
|
73
|
+
if audit.history_type == "-":
|
|
74
|
+
raise model.DoesNotExist
|
|
75
|
+
successor = (
|
|
76
|
+
self._timeline.filter(
|
|
77
|
+
models.Q(history_date__gt=audit.history_date)
|
|
78
|
+
| models.Q(
|
|
79
|
+
history_date=audit.history_date, history_id__gt=audit.history_id
|
|
80
|
+
)
|
|
81
|
+
)
|
|
82
|
+
.order_by("history_date", "history_id")
|
|
83
|
+
.first()
|
|
84
|
+
)
|
|
85
|
+
start = cast(datetime, audit.history_date).astimezone(UTC)
|
|
86
|
+
end = (
|
|
87
|
+
cast(datetime, cast(Any, successor).history_date).astimezone(UTC)
|
|
88
|
+
if successor is not None
|
|
89
|
+
else None
|
|
90
|
+
)
|
|
91
|
+
snapshot = resolve_search_date(self._search_date)
|
|
92
|
+
if snapshot is None:
|
|
93
|
+
snapshot = (
|
|
94
|
+
end - timedelta(microseconds=1) if end is not None else timezone.now()
|
|
95
|
+
)
|
|
96
|
+
instant = snapshot.astimezone(UTC)
|
|
97
|
+
if instant < start or (end is not None and instant >= end):
|
|
98
|
+
raise HistoricalContextConflictError
|
|
99
|
+
# A historical row's pk is its history_id, not the original entity id.
|
|
100
|
+
original_pk = getattr(row, model._meta.pk.attname)
|
|
101
|
+
with as_of(snapshot):
|
|
102
|
+
return self._manager_class(original_pk)
|
|
103
|
+
|
|
104
|
+
def all(self) -> ManagerHistoryQuery[ManagerT]:
|
|
105
|
+
return self._clone(self.raw.all())
|
|
106
|
+
|
|
107
|
+
def filter(self, *args: Any, **kwargs: Any) -> ManagerHistoryQuery[ManagerT]:
|
|
108
|
+
return self._clone(self.raw.filter(*args, **kwargs))
|
|
109
|
+
|
|
110
|
+
def exclude(self, *args: Any, **kwargs: Any) -> ManagerHistoryQuery[ManagerT]:
|
|
111
|
+
return self._clone(self.raw.exclude(*args, **kwargs))
|
|
112
|
+
|
|
113
|
+
def order_by(self, *fields: str) -> ManagerHistoryQuery[ManagerT]:
|
|
114
|
+
return self._clone(self.raw.order_by(*fields))
|
|
115
|
+
|
|
116
|
+
def reverse(self) -> ManagerHistoryQuery[ManagerT]:
|
|
117
|
+
return self._clone(self.raw.reverse())
|
|
118
|
+
|
|
119
|
+
def first(self) -> ManagerT | None:
|
|
120
|
+
"""Return the first selected version as a manager, or None."""
|
|
121
|
+
row = self._dated_query().first()
|
|
122
|
+
return None if row is None else self._materialize(row)
|
|
123
|
+
|
|
124
|
+
def last(self) -> ManagerT | None:
|
|
125
|
+
"""Return the last selected version as a manager, or None."""
|
|
126
|
+
row = self._dated_query().last()
|
|
127
|
+
return None if row is None else self._materialize(row)
|
|
128
|
+
|
|
129
|
+
def get(self, *args: Any, **kwargs: Any) -> ManagerT:
|
|
130
|
+
return self._materialize(self._dated_query().get(*args, **kwargs))
|
|
131
|
+
|
|
132
|
+
def latest(self, *fields: str) -> ManagerT:
|
|
133
|
+
return self._materialize(self._dated_query().latest(*fields))
|
|
134
|
+
|
|
135
|
+
def earliest(self, *fields: str) -> ManagerT:
|
|
136
|
+
return self._materialize(self._dated_query().earliest(*fields))
|
|
137
|
+
|
|
138
|
+
def count(self) -> int:
|
|
139
|
+
return self._dated_query().count()
|
|
140
|
+
|
|
141
|
+
def exists(self) -> bool:
|
|
142
|
+
return self._dated_query().exists()
|
|
143
|
+
|
|
144
|
+
def values(self, *fields: str, **expressions: Any) -> models.QuerySet[Any]:
|
|
145
|
+
return cast(
|
|
146
|
+
models.QuerySet[Any], self._dated_query().values(*fields, **expressions)
|
|
147
|
+
)
|
|
148
|
+
|
|
149
|
+
def values_list(self, *fields: str, **kwargs: Any) -> models.QuerySet[Any]:
|
|
150
|
+
return cast(
|
|
151
|
+
models.QuerySet[Any], self._dated_query().values_list(*fields, **kwargs)
|
|
152
|
+
)
|
|
153
|
+
|
|
154
|
+
def __iter__(self) -> Iterator[ManagerT]:
|
|
155
|
+
"""Materialize each selected audit version with its effective snapshot."""
|
|
156
|
+
for row in self._dated_query():
|
|
157
|
+
yield self._materialize(row)
|
|
158
|
+
|
|
159
|
+
def __len__(self) -> int:
|
|
160
|
+
return self.count()
|
|
161
|
+
|
|
162
|
+
def __bool__(self) -> bool:
|
|
163
|
+
return self.exists()
|
|
164
|
+
|
|
165
|
+
@overload
|
|
166
|
+
def __getitem__(self, key: int) -> ManagerT: ...
|
|
167
|
+
|
|
168
|
+
@overload
|
|
169
|
+
def __getitem__(self, key: slice) -> list[ManagerT]: ...
|
|
170
|
+
|
|
171
|
+
def __getitem__(self, key: int | slice) -> ManagerT | list[ManagerT]:
|
|
172
|
+
"""Materialize an indexed version or an eager list for a slice."""
|
|
173
|
+
if isinstance(key, int):
|
|
174
|
+
return self._materialize(self._dated_query()[key])
|
|
175
|
+
return [self._materialize(row) for row in self._dated_query()[key]]
|
|
176
|
+
|
|
177
|
+
def __repr__(self) -> str:
|
|
178
|
+
return f"ManagerHistoryQuery({self._manager_class.__name__})"
|
|
@@ -330,6 +330,7 @@ class OrmReadCapability(BaseCapability):
|
|
|
330
330
|
_ensure_ambient_history_supported(interface_cls, search_date)
|
|
331
331
|
|
|
332
332
|
def _perform() -> models.Model:
|
|
333
|
+
"""Load live or dated detail, rejecting absent and deleted versions."""
|
|
333
334
|
model_cls = interface_cls._model
|
|
334
335
|
support = get_support_capability(interface_cls)
|
|
335
336
|
only_active = not is_soft_delete_enabled(interface_cls)
|
|
@@ -387,6 +388,8 @@ class OrmReadCapability(BaseCapability):
|
|
|
387
388
|
) from error
|
|
388
389
|
raise
|
|
389
390
|
if historical is not None:
|
|
391
|
+
if getattr(historical, "history_type", None) == "-":
|
|
392
|
+
raise model_cls.DoesNotExist
|
|
390
393
|
return historical
|
|
391
394
|
if missing_error is not None:
|
|
392
395
|
raise missing_error
|
|
@@ -337,6 +337,11 @@ class _FieldDescriptorBuilder:
|
|
|
337
337
|
if target_field is not None and target_field.primary_key
|
|
338
338
|
else None
|
|
339
339
|
),
|
|
340
|
+
historical_lookup=(
|
|
341
|
+
(target_field.name, raw_id_name)
|
|
342
|
+
if target_field is not None and not target_field.primary_key
|
|
343
|
+
else None
|
|
344
|
+
),
|
|
340
345
|
)
|
|
341
346
|
relation_type = cast(type[object], general_manager_class)
|
|
342
347
|
else:
|
|
@@ -389,7 +394,12 @@ class _FieldDescriptorBuilder:
|
|
|
389
394
|
)
|
|
390
395
|
if general_manager_class:
|
|
391
396
|
accessor = _general_manager_accessor(
|
|
392
|
-
accessor_name,
|
|
397
|
+
accessor_name,
|
|
398
|
+
general_manager_class,
|
|
399
|
+
historical_lookup=(
|
|
400
|
+
relation.field.attname,
|
|
401
|
+
relation.field.target_field.attname,
|
|
402
|
+
),
|
|
393
403
|
)
|
|
394
404
|
relation_type = cast(type[object], general_manager_class)
|
|
395
405
|
else:
|
|
@@ -853,6 +863,7 @@ def _general_manager_accessor(
|
|
|
853
863
|
manager_class: type[object],
|
|
854
864
|
*,
|
|
855
865
|
raw_id_name: str | None = None,
|
|
866
|
+
historical_lookup: tuple[str, str] | None = None,
|
|
856
867
|
) -> DescriptorAccessor:
|
|
857
868
|
"""
|
|
858
869
|
Create an accessor that resolves a related object's manager from an interface.
|
|
@@ -867,6 +878,8 @@ def _general_manager_accessor(
|
|
|
867
878
|
field_name (str): Name of the attribute on the underlying model that holds the related object.
|
|
868
879
|
manager_class (type): Class used to hydrate or construct the related manager.
|
|
869
880
|
raw_id_name (str | None): Optional raw foreign-key attribute name used to avoid loading the relation.
|
|
881
|
+
historical_lookup: Target filter lookup and source attribute used to
|
|
882
|
+
resolve dated relations without consulting live Django relations.
|
|
870
883
|
|
|
871
884
|
Returns:
|
|
872
885
|
DescriptorAccessor: A callable that, given a OrmInterfaceBase, returns the manager instance for the related object, or `None` if the related attribute is `None`.
|
|
@@ -923,8 +936,16 @@ def _general_manager_accessor(
|
|
|
923
936
|
Returns:
|
|
924
937
|
The related manager instance, or `None` if the related object is `None`.
|
|
925
938
|
"""
|
|
939
|
+
search_date = getattr(self, "_search_date", None)
|
|
940
|
+
if search_date is not None and historical_lookup is not None:
|
|
941
|
+
lookup_name, source_attribute = historical_lookup
|
|
942
|
+
source_value = getattr(self._instance, source_attribute)
|
|
943
|
+
if source_value is None:
|
|
944
|
+
return None
|
|
945
|
+
return manager_type.filter(
|
|
946
|
+
**{lookup_name: source_value}, search_date=search_date
|
|
947
|
+
).first()
|
|
926
948
|
if raw_id_name is not None:
|
|
927
|
-
search_date = getattr(self, "_search_date", None)
|
|
928
949
|
raw_id = getattr(self._instance, raw_id_name, None)
|
|
929
950
|
if raw_id is None:
|
|
930
951
|
return None
|
|
@@ -949,7 +970,6 @@ def _general_manager_accessor(
|
|
|
949
970
|
return None
|
|
950
971
|
if related is None:
|
|
951
972
|
return None
|
|
952
|
-
search_date = getattr(self, "_search_date", None)
|
|
953
973
|
if search_date is not None:
|
|
954
974
|
return manager_type(related.pk, search_date=search_date)
|
|
955
975
|
trusted_hydrate = getattr(manager_type, "_from_trusted_orm_instance", None)
|
{generalmanager-0.87.2 → generalmanager-0.87.3}/src/general_manager/manager/general_manager.py
RENAMED
|
@@ -450,7 +450,7 @@ class GeneralManager(metaclass=GeneralManagerMeta):
|
|
|
450
450
|
|
|
451
451
|
@property
|
|
452
452
|
def history(self) -> object:
|
|
453
|
-
"""Return
|
|
453
|
+
"""Return scoped history; ORM results are managers with ``.raw`` audit access."""
|
|
454
454
|
from general_manager.interface.capabilities.orm import HistoryNotSupportedError
|
|
455
455
|
|
|
456
456
|
history_handler = self.Interface.get_capability_handler("history")
|
|
@@ -565,11 +565,16 @@ class GeneralManager(metaclass=GeneralManagerMeta):
|
|
|
565
565
|
yield key, value(self._interface)
|
|
566
566
|
continue
|
|
567
567
|
yield key, value
|
|
568
|
+
inherited_aliases = vars(self.__class__).get(
|
|
569
|
+
"_gm_inherited_property_aliases", {}
|
|
570
|
+
)
|
|
568
571
|
for name, value in self.__class__.__dict__.items():
|
|
569
572
|
if name == "history":
|
|
570
573
|
continue
|
|
571
574
|
if getattr(value, "_general_manager_generated_relation", False):
|
|
572
575
|
continue
|
|
576
|
+
if inherited_aliases.get(name, _EFFECTIVE_SEARCH_DATE_MISSING) is value:
|
|
577
|
+
continue
|
|
573
578
|
if isinstance(value, (GraphQLProperty, property)):
|
|
574
579
|
yield name, getattr(self, name)
|
|
575
580
|
|
|
@@ -664,7 +669,7 @@ class GeneralManager(metaclass=GeneralManagerMeta):
|
|
|
664
669
|
Raises:
|
|
665
670
|
PermissionError: If the permission check fails when `ignore_permission` is False.
|
|
666
671
|
"""
|
|
667
|
-
reject_historical_mutation()
|
|
672
|
+
reject_historical_mutation(self)
|
|
668
673
|
self._ensure_manager_not_invalidated()
|
|
669
674
|
if not ignore_permission:
|
|
670
675
|
self.Permission.check_update_permission(kwargs, self, creator_id)
|
|
@@ -710,7 +715,7 @@ class GeneralManager(metaclass=GeneralManagerMeta):
|
|
|
710
715
|
Raises:
|
|
711
716
|
PermissionError: If permission validation fails.
|
|
712
717
|
"""
|
|
713
|
-
reject_historical_mutation()
|
|
718
|
+
reject_historical_mutation(self)
|
|
714
719
|
self._ensure_manager_not_invalidated()
|
|
715
720
|
if not ignore_permission:
|
|
716
721
|
self.Permission.check_delete_permission(self, creator_id)
|