GeneralManager 0.52.2__tar.gz → 0.53.1__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.
Files changed (202) hide show
  1. {generalmanager-0.52.2/src/GeneralManager.egg-info → generalmanager-0.53.1}/PKG-INFO +1 -1
  2. {generalmanager-0.52.2 → generalmanager-0.53.1}/pyproject.toml +1 -1
  3. {generalmanager-0.52.2 → generalmanager-0.53.1/src/GeneralManager.egg-info}/PKG-INFO +1 -1
  4. {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/bucket/calculation_bucket.py +17 -17
  5. {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/bucket/database_bucket.py +128 -19
  6. {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/cache/run_context.py +10 -0
  7. {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/interface/orm_interface.py +29 -1
  8. {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/manager/general_manager.py +51 -1
  9. {generalmanager-0.52.2 → generalmanager-0.53.1}/LICENSE +0 -0
  10. {generalmanager-0.52.2 → generalmanager-0.53.1}/README.md +0 -0
  11. {generalmanager-0.52.2 → generalmanager-0.53.1}/setup.cfg +0 -0
  12. {generalmanager-0.52.2 → generalmanager-0.53.1}/src/GeneralManager.egg-info/SOURCES.txt +0 -0
  13. {generalmanager-0.52.2 → generalmanager-0.53.1}/src/GeneralManager.egg-info/dependency_links.txt +0 -0
  14. {generalmanager-0.52.2 → generalmanager-0.53.1}/src/GeneralManager.egg-info/requires.txt +0 -0
  15. {generalmanager-0.52.2 → generalmanager-0.53.1}/src/GeneralManager.egg-info/top_level.txt +0 -0
  16. {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/__init__.py +0 -0
  17. {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/_types/__init__.py +0 -0
  18. {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/_types/api.py +0 -0
  19. {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/_types/bucket.py +0 -0
  20. {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/_types/cache.py +0 -0
  21. {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/_types/factory.py +0 -0
  22. {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/_types/general_manager.py +0 -0
  23. {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/_types/interface.py +0 -0
  24. {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/_types/manager.py +0 -0
  25. {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/_types/measurement.py +0 -0
  26. {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/_types/permission.py +0 -0
  27. {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/_types/rule.py +0 -0
  28. {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/_types/search.py +0 -0
  29. {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/_types/utils.py +0 -0
  30. {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/api/__init__.py +0 -0
  31. {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/api/graphql.py +0 -0
  32. {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/api/graphql_errors.py +0 -0
  33. {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/api/graphql_mutations.py +0 -0
  34. {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/api/graphql_prefetch.py +0 -0
  35. {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/api/graphql_resolvers.py +0 -0
  36. {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/api/graphql_search.py +0 -0
  37. {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/api/graphql_subscription_consumer.py +0 -0
  38. {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/api/graphql_subscriptions.py +0 -0
  39. {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/api/graphql_view.py +0 -0
  40. {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/api/mutation.py +0 -0
  41. {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/api/property.py +0 -0
  42. {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/api/registry.py +0 -0
  43. {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/api/remote_api.py +0 -0
  44. {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/api/remote_invalidation.py +0 -0
  45. {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/api/remote_invalidation_client.py +0 -0
  46. {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/apps.py +0 -0
  47. {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/bootstrap.py +0 -0
  48. {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/bucket/__init__.py +0 -0
  49. {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/bucket/base_bucket.py +0 -0
  50. {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/bucket/group_bucket.py +0 -0
  51. {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/bucket/indexing.py +0 -0
  52. {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/bucket/request_bucket.py +0 -0
  53. {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/cache/__init__.py +0 -0
  54. {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/cache/cache_decorator.py +0 -0
  55. {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/cache/cache_tracker.py +0 -0
  56. {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/cache/dependency_cache.py +0 -0
  57. {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/cache/dependency_index.py +0 -0
  58. {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/cache/dependency_matching.py +0 -0
  59. {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/cache/dependency_publish.py +0 -0
  60. {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/cache/dependency_shards.py +0 -0
  61. {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/cache/model_dependency_collector.py +0 -0
  62. {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/cache/signals.py +0 -0
  63. {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/conf.py +0 -0
  64. {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/factory/__init__.py +0 -0
  65. {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/factory/auto_factory.py +0 -0
  66. {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/factory/factories.py +0 -0
  67. {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/factory/factory_methods.py +0 -0
  68. {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/interface/__init__.py +0 -0
  69. {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/interface/base_interface.py +0 -0
  70. {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/interface/bundles/__init__.py +0 -0
  71. {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/interface/bundles/calculation.py +0 -0
  72. {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/interface/bundles/database.py +0 -0
  73. {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/interface/bundles/remote_manager.py +0 -0
  74. {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/interface/bundles/request.py +0 -0
  75. {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/interface/capabilities/__init__.py +0 -0
  76. {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/interface/capabilities/base.py +0 -0
  77. {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/interface/capabilities/builtin.py +0 -0
  78. {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/interface/capabilities/calculation/__init__.py +0 -0
  79. {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/interface/capabilities/calculation/_compat.py +0 -0
  80. {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/interface/capabilities/calculation/lifecycle.py +0 -0
  81. {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/interface/capabilities/configuration.py +0 -0
  82. {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/interface/capabilities/core/observability.py +0 -0
  83. {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/interface/capabilities/core/utils.py +0 -0
  84. {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/interface/capabilities/exceptions.py +0 -0
  85. {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/interface/capabilities/existing_model/__init__.py +0 -0
  86. {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/interface/capabilities/existing_model/_compat.py +0 -0
  87. {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/interface/capabilities/existing_model/resolution.py +0 -0
  88. {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/interface/capabilities/factory.py +0 -0
  89. {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/interface/capabilities/orm/__init__.py +0 -0
  90. {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/interface/capabilities/orm/_compat.py +0 -0
  91. {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/interface/capabilities/orm/history.py +0 -0
  92. {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/interface/capabilities/orm/lifecycle.py +0 -0
  93. {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/interface/capabilities/orm/mutations.py +0 -0
  94. {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/interface/capabilities/orm/support.py +0 -0
  95. {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/interface/capabilities/orm_utils/__init__.py +0 -0
  96. {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/interface/capabilities/orm_utils/django_manager_utils.py +0 -0
  97. {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/interface/capabilities/orm_utils/field_descriptors.py +0 -0
  98. {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/interface/capabilities/orm_utils/payload_normalizer.py +0 -0
  99. {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/interface/capabilities/read_only/__init__.py +0 -0
  100. {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/interface/capabilities/read_only/_compat.py +0 -0
  101. {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/interface/capabilities/read_only/lifecycle.py +0 -0
  102. {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/interface/capabilities/read_only/management.py +0 -0
  103. {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/interface/capabilities/registry.py +0 -0
  104. {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/interface/capabilities/remote_manager.py +0 -0
  105. {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/interface/capabilities/request/__init__.py +0 -0
  106. {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/interface/infrastructure/__init__.py +0 -0
  107. {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/interface/infrastructure/startup_hooks.py +0 -0
  108. {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/interface/infrastructure/system_checks.py +0 -0
  109. {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/interface/interfaces/__init__.py +0 -0
  110. {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/interface/interfaces/calculation.py +0 -0
  111. {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/interface/interfaces/database.py +0 -0
  112. {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/interface/interfaces/existing_model.py +0 -0
  113. {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/interface/interfaces/read_only.py +0 -0
  114. {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/interface/interfaces/remote_manager.py +0 -0
  115. {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/interface/interfaces/request.py +0 -0
  116. {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/interface/manifests/__init__.py +0 -0
  117. {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/interface/manifests/capability_builder.py +0 -0
  118. {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/interface/manifests/capability_manifest.py +0 -0
  119. {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/interface/manifests/capability_models.py +0 -0
  120. {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/interface/requests.py +0 -0
  121. {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/interface/utils/__init__.py +0 -0
  122. {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/interface/utils/database_interface_protocols.py +0 -0
  123. {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/interface/utils/errors.py +0 -0
  124. {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/interface/utils/models.py +0 -0
  125. {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/logging.py +0 -0
  126. {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/management/commands/search_index.py +0 -0
  127. {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/management/commands/seed_manager_landscape.py +0 -0
  128. {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/management/commands/shell.py +0 -0
  129. {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/management/commands/workflow_drain_outbox.py +0 -0
  130. {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/management/commands/workflow_replay_dead_letters.py +0 -0
  131. {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/manager/__init__.py +0 -0
  132. {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/manager/group_manager.py +0 -0
  133. {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/manager/input.py +0 -0
  134. {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/manager/meta.py +0 -0
  135. {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/measurement/__init__.py +0 -0
  136. {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/measurement/measurement.py +0 -0
  137. {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/measurement/measurement_field.py +0 -0
  138. {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/metrics/__init__.py +0 -0
  139. {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/metrics/graphql.py +0 -0
  140. {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/migrations/0001_initial.py +0 -0
  141. {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/migrations/0002_workflow_outbox_scaling_indexes.py +0 -0
  142. {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/migrations/0003_workflow_execution_correlation_constraint.py +0 -0
  143. {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/migrations/__init__.py +0 -0
  144. {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/models.py +0 -0
  145. {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/permission/__init__.py +0 -0
  146. {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/permission/audit.py +0 -0
  147. {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/permission/base_permission.py +0 -0
  148. {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/permission/graphql_capabilities.py +0 -0
  149. {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/permission/manager_based_permission.py +0 -0
  150. {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/permission/mutation_permission.py +0 -0
  151. {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/permission/permission_checks.py +0 -0
  152. {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/permission/permission_data_manager.py +0 -0
  153. {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/permission/utils.py +0 -0
  154. {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/public_api_registry.py +0 -0
  155. {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/py.typed +0 -0
  156. {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/rule/__init__.py +0 -0
  157. {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/rule/handler.py +0 -0
  158. {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/rule/rule.py +0 -0
  159. {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/search/__init__.py +0 -0
  160. {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/search/async_tasks.py +0 -0
  161. {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/search/backend.py +0 -0
  162. {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/search/backend_registry.py +0 -0
  163. {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/search/backends/__init__.py +0 -0
  164. {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/search/backends/dev.py +0 -0
  165. {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/search/backends/meilisearch.py +0 -0
  166. {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/search/backends/opensearch.py +0 -0
  167. {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/search/backends/typesense.py +0 -0
  168. {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/search/config.py +0 -0
  169. {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/search/indexer.py +0 -0
  170. {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/search/registry.py +0 -0
  171. {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/search/utils.py +0 -0
  172. {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/seeding/__init__.py +0 -0
  173. {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/seeding/manager_landscape.py +0 -0
  174. {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/utils/__init__.py +0 -0
  175. {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/utils/args_to_kwargs.py +0 -0
  176. {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/utils/filter_parser.py +0 -0
  177. {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/utils/format_string.py +0 -0
  178. {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/utils/json_encoder.py +0 -0
  179. {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/utils/make_cache_key.py +0 -0
  180. {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/utils/none_to_zero.py +0 -0
  181. {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/utils/path_mapping.py +0 -0
  182. {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/utils/public_api.py +0 -0
  183. {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/utils/testing.py +0 -0
  184. {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/utils/type_checks.py +0 -0
  185. {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/workflow/__init__.py +0 -0
  186. {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/workflow/actions.py +0 -0
  187. {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/workflow/backend_registry.py +0 -0
  188. {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/workflow/backends/__init__.py +0 -0
  189. {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/workflow/backends/celery.py +0 -0
  190. {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/workflow/backends/local.py +0 -0
  191. {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/workflow/backends/n8n.py +0 -0
  192. {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/workflow/config.py +0 -0
  193. {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/workflow/engine.py +0 -0
  194. {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/workflow/event_registry.py +0 -0
  195. {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/workflow/events.py +0 -0
  196. {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/workflow/models.py +0 -0
  197. {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/workflow/signal_bridge.py +0 -0
  198. {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/workflow/tasks.py +0 -0
  199. {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/workflow/telemetry.py +0 -0
  200. {generalmanager-0.52.2 → generalmanager-0.53.1}/tests/test_settings.py +0 -0
  201. {generalmanager-0.52.2 → generalmanager-0.53.1}/tests/test_urls.py +0 -0
  202. {generalmanager-0.52.2 → generalmanager-0.53.1}/tests/testing_asgi.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: GeneralManager
3
- Version: 0.52.2
3
+ Version: 0.53.1
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.52.2"
7
+ version = "0.53.1"
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.52.2
3
+ Version: 0.53.1
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
@@ -521,21 +521,21 @@ class CalculationBucket(Bucket[GeneralManagerType]):
521
521
  if self._data is None:
522
522
  from general_manager.cache.run_context import ensure_calculation_run_context
523
523
 
524
- sorted_inputs = self.topological_sort_inputs()
525
- sorted_filters = self._sort_filters(sorted_inputs)
526
- current_combinations = self._generate_input_combinations(
527
- sorted_inputs,
528
- sorted_filters["input_filters"],
529
- sorted_filters["input_excludes"],
530
- )
531
- sort_key = self._normalized_sort_key()
532
- needs_manager_access = (
533
- bool(sorted_filters["prop_filters"])
534
- or bool(sorted_filters["prop_excludes"])
535
- or not self._sort_uses_only_inputs(sort_key)
536
- )
537
-
538
524
  with ensure_calculation_run_context():
525
+ sorted_inputs = self.topological_sort_inputs()
526
+ sorted_filters = self._sort_filters(sorted_inputs)
527
+ current_combinations = self._generate_input_combinations(
528
+ sorted_inputs,
529
+ sorted_filters["input_filters"],
530
+ sorted_filters["input_excludes"],
531
+ )
532
+ sort_key = self._normalized_sort_key()
533
+ needs_manager_access = (
534
+ bool(sorted_filters["prop_filters"])
535
+ or bool(sorted_filters["prop_excludes"])
536
+ or not self._sort_uses_only_inputs(sort_key)
537
+ )
538
+
539
539
  if needs_manager_access:
540
540
  manager_combinations = self._manager_combinations(
541
541
  current_combinations
@@ -564,9 +564,9 @@ class CalculationBucket(Bucket[GeneralManagerType]):
564
564
  sort_key,
565
565
  )
566
566
 
567
- if self.reverse:
568
- identifications.reverse()
569
- self._data = identifications
567
+ if self.reverse:
568
+ identifications.reverse()
569
+ self._data = identifications
570
570
 
571
571
  return self._data
572
572
 
@@ -257,11 +257,44 @@ class DatabaseBucket(Bucket[GeneralManagerType]):
257
257
  ),
258
258
  )
259
259
 
260
- def _build_manager(self, pk: Any) -> GeneralManagerType:
260
+ def _build_manager_from_primary_key(self, pk: Any) -> GeneralManagerType:
261
261
  if self._search_date is None:
262
262
  return self._manager_class(pk)
263
263
  return self._manager_class(pk, search_date=self._search_date)
264
264
 
265
+ def _can_trust_orm_instance(self, instance: models.Model) -> bool:
266
+ interface_model = getattr(self._manager_class.Interface, "_model", None)
267
+ if isinstance(interface_model, type) and issubclass(
268
+ interface_model, models.Model
269
+ ):
270
+ if not isinstance(instance, interface_model):
271
+ return False
272
+ get_deferred_fields = getattr(instance, "get_deferred_fields", None)
273
+ if callable(get_deferred_fields) and get_deferred_fields():
274
+ return False
275
+ if self._search_date is not None and not (
276
+ hasattr(instance, "_history") or hasattr(instance, "history_date")
277
+ ):
278
+ return False
279
+ return True
280
+
281
+ def _build_manager_from_instance(
282
+ self,
283
+ instance: models.Model,
284
+ ) -> GeneralManagerType:
285
+ interface_hydrate = getattr(
286
+ self._manager_class.Interface, "_from_trusted_orm_instance", None
287
+ )
288
+ manager_hydrate = self._manager_class._from_trusted_orm_instance
289
+ if callable(interface_hydrate) and self._can_trust_orm_instance(instance):
290
+ return manager_hydrate(instance, search_date=self._search_date)
291
+ return self._build_manager_from_primary_key(instance.pk)
292
+
293
+ def _build_manager(self, value: Any) -> GeneralManagerType:
294
+ if isinstance(value, models.Model):
295
+ return self._build_manager_from_instance(value)
296
+ return self._build_manager_from_primary_key(value)
297
+
265
298
  @staticmethod
266
299
  def _copy_filter_definitions(
267
300
  definitions: dict[str, Any] | None,
@@ -314,6 +347,11 @@ class DatabaseBucket(Bucket[GeneralManagerType]):
314
347
  return None
315
348
  if query.distinct:
316
349
  return None
350
+ if getattr(self._data, "_prefetch_related_lookups", ()):
351
+ return None
352
+ deferred_loading = getattr(query, "deferred_loading", None)
353
+ if isinstance(deferred_loading, tuple) and deferred_loading[0]:
354
+ return None
317
355
  try:
318
356
  sql, params = self._data.query.sql_with_params()
319
357
  except (EmptyResultSet, FieldError, TypeError, ValueError):
@@ -360,16 +398,44 @@ class DatabaseBucket(Bucket[GeneralManagerType]):
360
398
  if cached is not None:
361
399
  return cached # type: ignore[return-value]
362
400
 
363
- primary_keys = tuple(
364
- self._data.values_list("pk", flat=True)[
365
- : MAX_RUN_SCOPED_BUCKET_RESULT_ROWS + 1
366
- ]
367
- )
401
+ if self._data.ordered:
402
+ primary_keys = tuple(
403
+ self._data.values_list("pk", flat=True)[
404
+ : MAX_RUN_SCOPED_BUCKET_RESULT_ROWS + 1
405
+ ]
406
+ )
407
+ else:
408
+ # Preserve the order normal queryset iteration would expose.
409
+ primary_keys = tuple(
410
+ row.pk for row in self._data[: MAX_RUN_SCOPED_BUCKET_RESULT_ROWS + 1]
411
+ )
368
412
  if len(primary_keys) > MAX_RUN_SCOPED_BUCKET_RESULT_ROWS:
369
413
  return None
370
414
  context.set_orm_bucket_result(signature, primary_keys)
371
415
  return primary_keys
372
416
 
417
+ def _get_run_scoped_rows(self) -> tuple[models.Model, ...] | None:
418
+ """
419
+ Load or reuse a bounded model-row snapshot for trusted hydration.
420
+ """
421
+ context = current_calculation_run_context()
422
+ if context is None:
423
+ return None
424
+ signature = self._query_signature()
425
+ if signature is None:
426
+ return None
427
+ cached = context.get_orm_bucket_rows(signature)
428
+ if cached is not None:
429
+ return cached # type: ignore[return-value]
430
+
431
+ rows = tuple(self._data[: MAX_RUN_SCOPED_BUCKET_RESULT_ROWS + 1])
432
+ if len(rows) > MAX_RUN_SCOPED_BUCKET_RESULT_ROWS:
433
+ return None
434
+ primary_keys = tuple(row.pk for row in rows)
435
+ context.set_orm_bucket_rows(signature, rows)
436
+ context.set_orm_bucket_result(signature, primary_keys)
437
+ return rows
438
+
373
439
  def _peek_run_scoped_primary_keys(self) -> tuple[Any, ...] | None:
374
440
  """
375
441
  Return an already cached primary-key snapshot without evaluating the ORM.
@@ -393,6 +459,19 @@ class DatabaseBucket(Bucket[GeneralManagerType]):
393
459
  return None
394
460
  return cached # type: ignore[return-value]
395
461
 
462
+ def _peek_run_scoped_rows(self) -> tuple[models.Model, ...] | None:
463
+ """Return cached model rows without evaluating the ORM."""
464
+ context = current_calculation_run_context()
465
+ if context is None:
466
+ return None
467
+ signature = self._query_signature()
468
+ if signature is None:
469
+ return None
470
+ cached = context.get_orm_bucket_rows(signature)
471
+ if cached is None:
472
+ return None
473
+ return cached # type: ignore[return-value]
474
+
396
475
  @staticmethod
397
476
  def _snapshot_get_primary_key(kwargs: dict[str, Any]) -> Any | None:
398
477
  """
@@ -458,13 +537,18 @@ class DatabaseBucket(Bucket[GeneralManagerType]):
458
537
  GeneralManagerType: Manager instance for each primary key in the queryset.
459
538
  """
460
539
  self._track_effective_dependencies()
461
- primary_keys = self._get_run_scoped_primary_keys()
540
+ rows = self._get_run_scoped_rows()
541
+ if rows is not None:
542
+ for row in rows:
543
+ yield self._build_manager_from_instance(row)
544
+ return
545
+ primary_keys = self._peek_run_scoped_primary_keys()
462
546
  if primary_keys is not None:
463
547
  for primary_key in primary_keys:
464
- yield self._build_manager(primary_key)
548
+ yield self._build_manager_from_primary_key(primary_key)
465
549
  return
466
550
  for item in self._data:
467
- yield self._build_manager(item.pk)
551
+ yield self._build_manager_from_instance(item)
468
552
 
469
553
  def __or__(
470
554
  self,
@@ -585,7 +669,7 @@ class DatabaseBucket(Bucket[GeneralManagerType]):
585
669
  """
586
670
  ids: list[int] = []
587
671
  for obj in query_set:
588
- inst = self._build_manager(obj.pk)
672
+ inst = self._build_manager_from_instance(obj)
589
673
  keep = True
590
674
  for k, val, root in python_filters:
591
675
  lookup = k.split("__", 1)[1] if "__" in k else ""
@@ -704,15 +788,20 @@ class DatabaseBucket(Bucket[GeneralManagerType]):
704
788
  GeneralManagerType | None: First manager instance if available.
705
789
  """
706
790
  self._track_effective_dependencies()
791
+ rows = self._peek_run_scoped_rows()
792
+ if rows is not None:
793
+ if not rows:
794
+ return None
795
+ return self._build_manager_from_instance(rows[0])
707
796
  primary_keys = self._peek_run_scoped_primary_keys()
708
797
  if primary_keys is not None:
709
798
  if not primary_keys:
710
799
  return None
711
- return self._build_manager(primary_keys[0])
800
+ return self._build_manager_from_primary_key(primary_keys[0])
712
801
  first_element = self._data.first()
713
802
  if first_element is None:
714
803
  return None
715
- return self._build_manager(first_element.pk)
804
+ return self._build_manager_from_instance(first_element)
716
805
 
717
806
  def last(self) -> GeneralManagerType | None:
718
807
  """
@@ -722,15 +811,20 @@ class DatabaseBucket(Bucket[GeneralManagerType]):
722
811
  GeneralManagerType | None: Last manager instance if available.
723
812
  """
724
813
  self._track_effective_dependencies()
814
+ rows = self._peek_run_scoped_rows()
815
+ if rows is not None:
816
+ if not rows:
817
+ return None
818
+ return self._build_manager_from_instance(rows[-1])
725
819
  primary_keys = self._peek_run_scoped_primary_keys()
726
820
  if primary_keys is not None:
727
821
  if not primary_keys:
728
822
  return None
729
- return self._build_manager(primary_keys[-1])
823
+ return self._build_manager_from_primary_key(primary_keys[-1])
730
824
  first_element = self._data.last()
731
825
  if first_element is None:
732
826
  return None
733
- return self._build_manager(first_element.pk)
827
+ return self._build_manager_from_instance(first_element)
734
828
 
735
829
  def count(self) -> int:
736
830
  """
@@ -778,18 +872,28 @@ class DatabaseBucket(Bucket[GeneralManagerType]):
778
872
  models.MultipleObjectsReturned: Propagated when multiple rows satisfy the lookup.
779
873
  """
780
874
  self._track_effective_dependencies()
875
+ rows = self._peek_run_scoped_rows()
876
+ if rows is not None:
877
+ requested_primary_key = self._snapshot_get_primary_key(kwargs)
878
+ if requested_primary_key is not None:
879
+ matches = [row for row in rows if row.pk == requested_primary_key]
880
+ if len(matches) == 1:
881
+ return self._build_manager_from_instance(matches[0])
882
+ if len(matches) > 1:
883
+ raise self._data.model.MultipleObjectsReturned
884
+ raise self._data.model.DoesNotExist
781
885
  primary_keys = self._peek_run_scoped_primary_keys()
782
886
  if primary_keys is not None:
783
887
  requested_primary_key = self._snapshot_get_primary_key(kwargs)
784
888
  if requested_primary_key is not None:
785
889
  match_count = primary_keys.count(requested_primary_key)
786
890
  if match_count == 1:
787
- return self._build_manager(requested_primary_key)
891
+ return self._build_manager_from_primary_key(requested_primary_key)
788
892
  if match_count > 1:
789
893
  raise self._data.model.MultipleObjectsReturned
790
894
  raise self._data.model.DoesNotExist
791
895
  element = self._data.get(**kwargs)
792
- return self._build_manager(element.pk)
896
+ return self._build_manager_from_instance(element)
793
897
 
794
898
  def __getitem__(
795
899
  self, item: int | slice
@@ -815,12 +919,17 @@ class DatabaseBucket(Bucket[GeneralManagerType]):
815
919
  run_scoped_cacheable=self._run_scoped_cacheable,
816
920
  )
817
921
  self._track_effective_dependencies()
922
+ rows = self._peek_run_scoped_rows()
923
+ if rows is not None:
924
+ if item < 0:
925
+ raise ValueError
926
+ return self._build_manager_from_instance(rows[item])
818
927
  primary_keys = self._peek_run_scoped_primary_keys()
819
928
  if primary_keys is not None:
820
929
  if item < 0:
821
930
  raise ValueError
822
- return self._build_manager(primary_keys[item])
823
- return self._build_manager(self._data[item].pk)
931
+ return self._build_manager_from_primary_key(primary_keys[item])
932
+ return self._build_manager_from_instance(self._data[item])
824
933
 
825
934
  def __len__(self) -> int:
826
935
  """
@@ -926,7 +1035,7 @@ class DatabaseBucket(Bucket[GeneralManagerType]):
926
1035
  objs = list(qs)
927
1036
 
928
1037
  def key_func(obj: models.Model) -> tuple[object, ...]:
929
- inst = self._build_manager(obj.pk)
1038
+ inst = self._build_manager_from_instance(obj)
930
1039
  values = []
931
1040
  for k in key:
932
1041
  if k in properties:
@@ -26,6 +26,7 @@ _active_context: ContextVar["CalculationRunContext | None"] = ContextVar(
26
26
  default=None,
27
27
  )
28
28
  ORM_BUCKET_RESULT_PREFIX = "orm_bucket_result"
29
+ ORM_BUCKET_ROW_RESULT_PREFIX = "orm_bucket_row_result"
29
30
  BUCKET_INDEX_PREFIX = "bucket_index"
30
31
  DEFAULT_DEPENDENCY_CACHE_PUBLISH_BATCH_SIZE = 1000
31
32
  logger = get_logger("cache.run_context")
@@ -191,9 +192,18 @@ class CalculationRunContext:
191
192
  """Store an ORM bucket result for the active run."""
192
193
  self.set((ORM_BUCKET_RESULT_PREFIX, key), value)
193
194
 
195
+ def get_orm_bucket_rows(self, key: Hashable) -> object:
196
+ """Return cached ORM bucket rows for key, or None when absent."""
197
+ return self.get((ORM_BUCKET_ROW_RESULT_PREFIX, key))
198
+
199
+ def set_orm_bucket_rows(self, key: Hashable, value: object) -> None:
200
+ """Store ORM bucket rows for the active run."""
201
+ self.set((ORM_BUCKET_ROW_RESULT_PREFIX, key), value)
202
+
194
203
  def clear_orm_bucket_results(self) -> None:
195
204
  """Discard all run-scoped ORM bucket result entries."""
196
205
  self.discard_prefix((ORM_BUCKET_RESULT_PREFIX,))
206
+ self.discard_prefix((ORM_BUCKET_ROW_RESULT_PREFIX,))
197
207
 
198
208
  def _bucket_index_cache_key(
199
209
  self,
@@ -3,7 +3,7 @@
3
3
  from __future__ import annotations
4
4
 
5
5
  from datetime import datetime
6
- from typing import ClassVar, Generic, Type, TypeVar, cast
6
+ from typing import Any, ClassVar, Generic, Type, TypeVar, cast
7
7
 
8
8
  from django.db import models
9
9
  from django.utils import timezone
@@ -60,6 +60,34 @@ class OrmInterfaceBase(InterfaceBase, Generic[HistoryModelT]):
60
60
  self._search_date = self.normalize_search_date(search_date)
61
61
  self._instance: HistoryModelT = self.get_data()
62
62
 
63
+ @classmethod
64
+ def _from_trusted_orm_instance(
65
+ cls,
66
+ instance: HistoryModelT,
67
+ *,
68
+ search_date: datetime | None = None,
69
+ ) -> "OrmInterfaceBase[HistoryModelT]":
70
+ """
71
+ Build an interface from an ORM-loaded row without public input validation.
72
+
73
+ This is an internal trusted path. Callers must only pass model or
74
+ historical rows that came from Django ORM querysets owned by this
75
+ interface. External/API/user payloads must continue through __init__.
76
+ """
77
+ pk = cast(Any, instance).pk
78
+ if cls.__init__ is not OrmInterfaceBase.__init__:
79
+ if search_date is None:
80
+ return cls(pk)
81
+ return cls(pk, search_date=search_date)
82
+
83
+ interface = cls.__new__(cls)
84
+ identification = {"id": pk}
85
+ interface.identification = identification
86
+ interface.pk = pk
87
+ interface._search_date = cls.normalize_search_date(search_date)
88
+ interface._instance = instance
89
+ return interface
90
+
63
91
  @staticmethod
64
92
  def normalize_search_date(search_date: datetime | None) -> datetime | None:
65
93
  """
@@ -1,6 +1,6 @@
1
1
  from __future__ import annotations
2
2
  from collections.abc import Mapping
3
- from typing import TYPE_CHECKING, Any, Iterator, Self, Type
3
+ from typing import TYPE_CHECKING, Any, Iterator, Self, Type, cast
4
4
 
5
5
  from general_manager.api.property import GraphQLProperty
6
6
  from general_manager.bucket.base_bucket import Bucket
@@ -24,6 +24,13 @@ class UnsupportedUnionOperandError(TypeError):
24
24
  super().__init__(f"Unsupported type for union: {operand_type}.")
25
25
 
26
26
 
27
+ class TrustedOrmHydrationNotSupportedError(TypeError):
28
+ """Raised when trusted ORM hydration is requested for a non-ORM interface."""
29
+
30
+ def __init__(self, interface_name: str) -> None:
31
+ super().__init__(f"{interface_name} does not support trusted ORM hydration.")
32
+
33
+
27
34
  if TYPE_CHECKING:
28
35
  from general_manager.permission.base_permission import BasePermission
29
36
  from general_manager.interface.base_interface import InterfaceBase
@@ -65,6 +72,49 @@ class GeneralManager(metaclass=GeneralManagerMeta):
65
72
  },
66
73
  )
67
74
 
75
+ @classmethod
76
+ def _from_trusted_orm_instance(
77
+ cls,
78
+ instance: Any,
79
+ *,
80
+ search_date: Any = None,
81
+ ) -> Self:
82
+ """
83
+ Build a manager around an ORM-loaded row without public input validation.
84
+
85
+ This private path is only for framework-owned Django ORM rows. It must
86
+ not be used for GraphQL, mutation, import, factory, or other external
87
+ payloads because it bypasses Interface input validation.
88
+ """
89
+ hydrate = getattr(cls.Interface, "_from_trusted_orm_instance", None)
90
+ if not callable(hydrate):
91
+ raise TrustedOrmHydrationNotSupportedError(cls.Interface.__name__)
92
+
93
+ if cls.__init__ is not GeneralManager.__init__:
94
+ pk = instance.pk
95
+ if search_date is None:
96
+ return cls(pk)
97
+ return cls(pk, search_date=search_date)
98
+
99
+ manager = cls.__new__(cls)
100
+ manager._interface = hydrate(instance, search_date=search_date)
101
+ manager.__id = manager._interface.identification
102
+ manager._manager_state_valid = True
103
+ manager._manager_state_reason = None
104
+ DependencyTracker.track(
105
+ cls.__name__,
106
+ "identification",
107
+ serialize_dependency_identifier(manager.__id),
108
+ )
109
+ logger.debug(
110
+ "trusted orm manager hydrated",
111
+ context={
112
+ "manager": cls.__name__,
113
+ "identification": manager.__id,
114
+ },
115
+ )
116
+ return cast(Self, manager)
117
+
68
118
  def __str__(self) -> str:
69
119
  """Return a user-friendly representation showing the identification."""
70
120
  return f"{self.__class__.__name__}(**{self.__id})"
File without changes