GeneralManager 0.78.0__tar.gz → 0.79.0__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 (332) hide show
  1. {generalmanager-0.78.0/src/GeneralManager.egg-info → generalmanager-0.79.0}/PKG-INFO +1 -1
  2. {generalmanager-0.78.0 → generalmanager-0.79.0}/pyproject.toml +2 -2
  3. {generalmanager-0.78.0 → generalmanager-0.79.0/src/GeneralManager.egg-info}/PKG-INFO +1 -1
  4. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/GeneralManager.egg-info/SOURCES.txt +10 -3
  5. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/_types/utils.py +3 -3
  6. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/api/graphql.py +246 -89
  7. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/api/graphql_errors.py +10 -11
  8. generalmanager-0.79.0/src/general_manager/api/graphql_groups.py +341 -0
  9. generalmanager-0.79.0/src/general_manager/api/graphql_ordering.py +249 -0
  10. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/api/graphql_output.py +2 -10
  11. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/api/graphql_prefetch.py +1 -1
  12. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/api/graphql_resolvers.py +421 -103
  13. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/api/graphql_search.py +189 -76
  14. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/api/graphql_subscription_consumer.py +13 -0
  15. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/api/graphql_warmup.py +1 -1
  16. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/api/graphql_warmup_registry.py +1 -1
  17. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/api/mutation.py +123 -51
  18. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/api/registry.py +3 -0
  19. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/api/remote_api.py +222 -35
  20. generalmanager-0.79.0/src/general_manager/bucket/_materialized_bucket.py +211 -0
  21. generalmanager-0.79.0/src/general_manager/bucket/_ordering.py +335 -0
  22. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/bucket/base_bucket.py +6 -8
  23. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/bucket/calculation_bucket.py +256 -134
  24. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/bucket/database_bucket.py +389 -91
  25. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/bucket/excel_bucket.py +119 -28
  26. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/bucket/group_bucket.py +13 -18
  27. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/bucket/request_bucket.py +209 -55
  28. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/cache/cache_decorator.py +158 -37
  29. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/cache/dependency_cache.py +10 -9
  30. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/cache/run_context.py +23 -17
  31. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/chat/consumer.py +273 -71
  32. generalmanager-0.79.0/src/general_manager/chat/context.py +109 -0
  33. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/chat/evals/__main__.py +2 -3
  34. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/chat/models.py +271 -17
  35. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/chat/planned/config.py +4 -1
  36. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/chat/planned/evidence.py +6 -1
  37. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/chat/providers/anthropic.py +30 -3
  38. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/chat/providers/base.py +14 -7
  39. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/chat/providers/google.py +83 -20
  40. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/chat/providers/ollama.py +76 -28
  41. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/chat/providers/openai.py +28 -4
  42. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/chat/system_prompt.py +3 -2
  43. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/chat/tool_metadata.py +2 -6
  44. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/chat/tools.py +15 -1
  45. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/chat/views.py +194 -100
  46. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/factory/auto_factory.py +209 -35
  47. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/factory/factory_methods.py +1 -1
  48. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/interface/base_interface.py +1 -1
  49. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/interface/bundles/remote_manager.py +6 -6
  50. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/interface/capabilities/read_only/management.py +111 -29
  51. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/interface/capabilities/remote_manager.py +195 -8
  52. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/interface/capabilities/request/__init__.py +362 -33
  53. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/interface/interfaces/remote_manager.py +20 -1
  54. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/interface/interfaces/request.py +6 -3
  55. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/interface/requests.py +91 -4
  56. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/logging.py +23 -12
  57. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/management/commands/chat_cleanup.py +3 -1
  58. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/management/commands/graphql_warmup.py +17 -3
  59. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/management/commands/seed_manager_landscape.py +2 -0
  60. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/manager/group_manager.py +77 -1
  61. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/manager/input.py +179 -52
  62. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/measurement/measurement.py +367 -125
  63. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/measurement/measurement_field.py +128 -4
  64. generalmanager-0.79.0/src/general_manager/migrations/0012_chat_context_watermarks.py +34 -0
  65. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/permission/audit.py +139 -43
  66. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/permission/base_permission.py +48 -2
  67. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/permission/manager_based_permission.py +8 -4
  68. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/permission/mutation_permission.py +12 -7
  69. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/public_api_registry.py +3 -3
  70. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/rule/rule.py +214 -5
  71. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/search/backend.py +4 -5
  72. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/search/backends/dev.py +38 -26
  73. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/search/backends/meilisearch.py +84 -41
  74. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/search/backends/opensearch.py +2 -4
  75. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/search/backends/typesense.py +2 -4
  76. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/search/config.py +33 -0
  77. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/search/indexer.py +8 -10
  78. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/seeding/manager_landscape.py +80 -10
  79. generalmanager-0.79.0/src/general_manager/utils/_cache_key_encoder.py +225 -0
  80. generalmanager-0.79.0/src/general_manager/utils/_make_cache_key.py +171 -0
  81. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/utils/testing.py +34 -7
  82. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/workflow/__init__.py +6 -0
  83. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/workflow/backends/celery.py +15 -14
  84. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/workflow/backends/local.py +22 -9
  85. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/workflow/event_registry.py +192 -31
  86. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/workflow/tasks.py +29 -9
  87. generalmanager-0.78.0/src/general_manager/utils/make_cache_key.py +0 -192
  88. {generalmanager-0.78.0 → generalmanager-0.79.0}/LICENSE +0 -0
  89. {generalmanager-0.78.0 → generalmanager-0.79.0}/README.md +0 -0
  90. {generalmanager-0.78.0 → generalmanager-0.79.0}/setup.cfg +0 -0
  91. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/GeneralManager.egg-info/dependency_links.txt +0 -0
  92. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/GeneralManager.egg-info/requires.txt +0 -0
  93. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/GeneralManager.egg-info/top_level.txt +0 -0
  94. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/__init__.py +0 -0
  95. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/_types/__init__.py +0 -0
  96. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/_types/api.py +0 -0
  97. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/_types/bucket.py +0 -0
  98. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/_types/cache.py +0 -0
  99. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/_types/dataframes.py +0 -0
  100. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/_types/factory.py +0 -0
  101. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/_types/general_manager.py +0 -0
  102. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/_types/interface.py +0 -0
  103. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/_types/manager.py +0 -0
  104. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/_types/measurement.py +0 -0
  105. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/_types/permission.py +0 -0
  106. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/_types/rule.py +0 -0
  107. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/_types/search.py +0 -0
  108. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/api/__init__.py +0 -0
  109. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/api/graphql_as_of.py +0 -0
  110. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/api/graphql_mutations.py +0 -0
  111. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/api/graphql_relations.py +0 -0
  112. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/api/graphql_subscriptions.py +0 -0
  113. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/api/graphql_type.py +0 -0
  114. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/api/graphql_view.py +0 -0
  115. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/api/graphql_warmup_tasks.py +0 -0
  116. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/api/notification_batching.py +0 -0
  117. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/api/property.py +0 -0
  118. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/api/remote_invalidation.py +0 -0
  119. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/api/remote_invalidation_client.py +0 -0
  120. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/apps.py +0 -0
  121. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/as_of.py +0 -0
  122. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/bootstrap.py +0 -0
  123. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/bucket/__init__.py +0 -0
  124. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/bucket/indexing.py +0 -0
  125. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/bucket/projection.py +0 -0
  126. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/cache/__init__.py +0 -0
  127. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/cache/cache_tracker.py +0 -0
  128. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/cache/data_change_context.py +0 -0
  129. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/cache/dependency_index.py +0 -0
  130. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/cache/dependency_matching.py +0 -0
  131. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/cache/dependency_publish.py +0 -0
  132. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/cache/dependency_shards.py +0 -0
  133. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/cache/model_dependency_collector.py +0 -0
  134. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/cache/run_context_lru.py +0 -0
  135. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/cache/signals.py +0 -0
  136. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/chat/__init__.py +0 -0
  137. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/chat/audit.py +0 -0
  138. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/chat/bootstrap.py +0 -0
  139. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/chat/checks.py +0 -0
  140. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/chat/errors.py +0 -0
  141. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/chat/evals/__init__.py +0 -0
  142. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/chat/evals/baseline.py +0 -0
  143. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/chat/evals/datasets/basic_queries.yaml +0 -0
  144. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/chat/evals/datasets/demo_readiness.yaml +0 -0
  145. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/chat/evals/datasets/edge_cases.yaml +0 -0
  146. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/chat/evals/datasets/follow_ups.yaml +0 -0
  147. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/chat/evals/datasets/large_schema.yaml +0 -0
  148. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/chat/evals/datasets/multi_hop.yaml +0 -0
  149. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/chat/evals/datasets/planned_orchestration.yaml +0 -0
  150. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/chat/evals/diagnostics.py +0 -0
  151. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/chat/evals/fingerprints.py +0 -0
  152. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/chat/evals/fixtures.py +0 -0
  153. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/chat/evals/judges/__init__.py +0 -0
  154. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/chat/evals/judges/answer_quality.py +0 -0
  155. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/chat/evals/judges/contract.py +0 -0
  156. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/chat/evals/judges/result_accuracy.py +0 -0
  157. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/chat/evals/judges/tool_sequence.py +0 -0
  158. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/chat/evals/readiness.py +0 -0
  159. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/chat/evals/runner.py +0 -0
  160. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/chat/evals/traces.py +0 -0
  161. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/chat/grounding.py +0 -0
  162. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/chat/planned/__init__.py +0 -0
  163. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/chat/planned/budget.py +0 -0
  164. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/chat/planned/calculations.py +0 -0
  165. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/chat/planned/catalog.py +0 -0
  166. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/chat/planned/events.py +0 -0
  167. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/chat/planned/models.py +0 -0
  168. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/chat/planned/planner.py +0 -0
  169. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/chat/planned/provider_calls.py +0 -0
  170. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/chat/planned/resolver.py +0 -0
  171. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/chat/planned/routing.py +0 -0
  172. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/chat/planned/scheduler.py +0 -0
  173. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/chat/planned/synthesis.py +0 -0
  174. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/chat/planned/validation.py +0 -0
  175. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/chat/providers/__init__.py +0 -0
  176. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/chat/providers/_shared.py +0 -0
  177. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/chat/rate_limits.py +0 -0
  178. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/chat/routing.py +0 -0
  179. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/chat/schema_index.py +0 -0
  180. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/chat/settings.py +0 -0
  181. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/chat/signals.py +0 -0
  182. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/conf.py +0 -0
  183. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/dataframes/__init__.py +0 -0
  184. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/dataframes/measurements.py +0 -0
  185. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/factory/__init__.py +0 -0
  186. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/factory/factories.py +0 -0
  187. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/interface/__init__.py +0 -0
  188. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/interface/bundles/__init__.py +0 -0
  189. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/interface/bundles/calculation.py +0 -0
  190. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/interface/bundles/database.py +0 -0
  191. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/interface/bundles/excel.py +0 -0
  192. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/interface/bundles/request.py +0 -0
  193. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/interface/capabilities/__init__.py +0 -0
  194. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/interface/capabilities/base.py +0 -0
  195. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/interface/capabilities/builtin.py +0 -0
  196. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/interface/capabilities/calculation/__init__.py +0 -0
  197. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/interface/capabilities/calculation/_compat.py +0 -0
  198. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/interface/capabilities/calculation/input_resolution.py +0 -0
  199. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/interface/capabilities/calculation/lifecycle.py +0 -0
  200. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/interface/capabilities/configuration.py +0 -0
  201. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/interface/capabilities/core/observability.py +0 -0
  202. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/interface/capabilities/core/utils.py +0 -0
  203. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/interface/capabilities/excel/__init__.py +0 -0
  204. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/interface/capabilities/exceptions.py +0 -0
  205. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/interface/capabilities/existing_model/__init__.py +0 -0
  206. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/interface/capabilities/existing_model/_compat.py +0 -0
  207. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/interface/capabilities/existing_model/resolution.py +0 -0
  208. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/interface/capabilities/factory.py +0 -0
  209. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/interface/capabilities/orm/__init__.py +0 -0
  210. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/interface/capabilities/orm/_compat.py +0 -0
  211. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/interface/capabilities/orm/history.py +0 -0
  212. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/interface/capabilities/orm/lifecycle.py +0 -0
  213. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/interface/capabilities/orm/mutations.py +0 -0
  214. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/interface/capabilities/orm/support.py +0 -0
  215. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/interface/capabilities/orm_utils/__init__.py +0 -0
  216. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/interface/capabilities/orm_utils/django_manager_utils.py +0 -0
  217. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/interface/capabilities/orm_utils/field_descriptors.py +0 -0
  218. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/interface/capabilities/orm_utils/payload_normalizer.py +0 -0
  219. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/interface/capabilities/read_only/__init__.py +0 -0
  220. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/interface/capabilities/read_only/_compat.py +0 -0
  221. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/interface/capabilities/read_only/_types.py +0 -0
  222. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/interface/capabilities/read_only/lifecycle.py +0 -0
  223. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/interface/capabilities/registry.py +0 -0
  224. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/interface/excel.py +0 -0
  225. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/interface/excel_store.py +0 -0
  226. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/interface/excel_workbook.py +0 -0
  227. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/interface/infrastructure/__init__.py +0 -0
  228. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/interface/infrastructure/startup_hooks.py +0 -0
  229. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/interface/infrastructure/system_checks.py +0 -0
  230. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/interface/interfaces/__init__.py +0 -0
  231. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/interface/interfaces/calculation.py +0 -0
  232. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/interface/interfaces/database.py +0 -0
  233. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/interface/interfaces/excel.py +0 -0
  234. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/interface/interfaces/existing_model.py +0 -0
  235. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/interface/interfaces/read_only.py +0 -0
  236. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/interface/manifests/__init__.py +0 -0
  237. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/interface/manifests/capability_builder.py +0 -0
  238. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/interface/manifests/capability_manifest.py +0 -0
  239. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/interface/manifests/capability_models.py +0 -0
  240. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/interface/orm_interface.py +0 -0
  241. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/interface/utils/__init__.py +0 -0
  242. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/interface/utils/database_interface_protocols.py +0 -0
  243. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/interface/utils/errors.py +0 -0
  244. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/interface/utils/history.py +0 -0
  245. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/interface/utils/models.py +0 -0
  246. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/management/commands/cleanup_upload_intents.py +0 -0
  247. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/management/commands/graphql_warmup_refresh_due.py +0 -0
  248. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/management/commands/search_index.py +0 -0
  249. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/management/commands/search_reconcile.py +0 -0
  250. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/management/commands/shell.py +0 -0
  251. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/management/commands/workflow_drain_outbox.py +0 -0
  252. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/management/commands/workflow_replay_dead_letters.py +0 -0
  253. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/manager/__init__.py +0 -0
  254. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/manager/general_manager.py +0 -0
  255. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/manager/meta.py +0 -0
  256. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/measurement/__init__.py +0 -0
  257. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/metrics/__init__.py +0 -0
  258. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/metrics/graphql.py +0 -0
  259. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/migrations/0001_initial.py +0 -0
  260. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/migrations/0002_workflow_outbox_scaling_indexes.py +0 -0
  261. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/migrations/0003_workflow_execution_correlation_constraint.py +0 -0
  262. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/migrations/0004_chat_persistence_models.py +0 -0
  263. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/migrations/0004_search_index_state.py +0 -0
  264. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/migrations/0005_merge_chat_search.py +0 -0
  265. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/migrations/0006_chat_pending_confirmation_scoped_ids.py +0 -0
  266. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/migrations/0007_upload_intent.py +0 -0
  267. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/migrations/0008_upload_finalization_versions.py +0 -0
  268. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/migrations/0009_upload_cleanup_state.py +0 -0
  269. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/migrations/0010_chat_pending_confirmation_portable_uniqueness.py +0 -0
  270. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/migrations/0011_search_index_state_dirty_generation.py +0 -0
  271. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/migrations/__init__.py +0 -0
  272. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/models.py +0 -0
  273. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/permission/__init__.py +0 -0
  274. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/permission/graphql_capabilities.py +0 -0
  275. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/permission/permission_checks.py +0 -0
  276. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/permission/permission_data_manager.py +0 -0
  277. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/permission/utils.py +0 -0
  278. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/py.typed +0 -0
  279. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/rule/__init__.py +0 -0
  280. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/rule/handler.py +0 -0
  281. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/search/__init__.py +0 -0
  282. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/search/async_tasks.py +0 -0
  283. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/search/backend_registry.py +0 -0
  284. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/search/backends/__init__.py +0 -0
  285. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/search/checks.py +0 -0
  286. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/search/invalidation.py +0 -0
  287. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/search/m2m_invalidation.py +0 -0
  288. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/search/models.py +0 -0
  289. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/search/reconciliation.py +0 -0
  290. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/search/registry.py +0 -0
  291. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/search/tasks.py +0 -0
  292. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/search/utils.py +0 -0
  293. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/seeding/__init__.py +0 -0
  294. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/uploads/__init__.py +0 -0
  295. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/uploads/adapters.py +0 -0
  296. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/uploads/checks.py +0 -0
  297. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/uploads/config.py +0 -0
  298. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/uploads/errors.py +0 -0
  299. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/uploads/finalization.py +0 -0
  300. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/uploads/graphql.py +0 -0
  301. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/uploads/graphql_types.py +0 -0
  302. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/uploads/metrics.py +0 -0
  303. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/uploads/models.py +0 -0
  304. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/uploads/public.py +0 -0
  305. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/uploads/s3.py +0 -0
  306. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/uploads/services.py +0 -0
  307. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/uploads/tokens.py +0 -0
  308. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/uploads/types.py +0 -0
  309. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/uploads/urls.py +0 -0
  310. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/uploads/views.py +0 -0
  311. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/utils/__init__.py +0 -0
  312. /generalmanager-0.78.0/src/general_manager/utils/args_to_kwargs.py → /generalmanager-0.79.0/src/general_manager/utils/_args_to_kwargs.py +0 -0
  313. /generalmanager-0.78.0/src/general_manager/utils/none_to_zero.py → /generalmanager-0.79.0/src/general_manager/utils/_none_to_zero.py +0 -0
  314. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/utils/filter_parser.py +0 -0
  315. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/utils/format_string.py +0 -0
  316. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/utils/json_encoder.py +0 -0
  317. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/utils/path_mapping.py +0 -0
  318. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/utils/public_api.py +0 -0
  319. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/utils/type_checks.py +0 -0
  320. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/workflow/actions.py +0 -0
  321. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/workflow/backend_registry.py +0 -0
  322. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/workflow/backends/__init__.py +0 -0
  323. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/workflow/backends/n8n.py +0 -0
  324. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/workflow/config.py +0 -0
  325. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/workflow/engine.py +0 -0
  326. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/workflow/events.py +0 -0
  327. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/workflow/models.py +0 -0
  328. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/workflow/signal_bridge.py +0 -0
  329. {generalmanager-0.78.0 → generalmanager-0.79.0}/src/general_manager/workflow/telemetry.py +0 -0
  330. {generalmanager-0.78.0 → generalmanager-0.79.0}/tests/test_settings.py +0 -0
  331. {generalmanager-0.78.0 → generalmanager-0.79.0}/tests/test_urls.py +0 -0
  332. {generalmanager-0.78.0 → generalmanager-0.79.0}/tests/testing_asgi.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: GeneralManager
3
- Version: 0.78.0
3
+ Version: 0.79.0
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.78.0"
7
+ version = "0.79.0"
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" }]
@@ -153,7 +153,7 @@ strict = true
153
153
  explicit_package_bases = true
154
154
  namespace_packages = true
155
155
  mypy_path = ["src"]
156
- files = ["src"]
156
+ files = ["src", "tests/typing"]
157
157
  exclude = ["^build/", "^dist/", "^docs/", "^example_project/", "^site/"]
158
158
 
159
159
  [[tool.mypy.overrides]]
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: GeneralManager
3
- Version: 0.78.0
3
+ Version: 0.79.0
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
@@ -33,7 +33,9 @@ src/general_manager/api/__init__.py
33
33
  src/general_manager/api/graphql.py
34
34
  src/general_manager/api/graphql_as_of.py
35
35
  src/general_manager/api/graphql_errors.py
36
+ src/general_manager/api/graphql_groups.py
36
37
  src/general_manager/api/graphql_mutations.py
38
+ src/general_manager/api/graphql_ordering.py
37
39
  src/general_manager/api/graphql_output.py
38
40
  src/general_manager/api/graphql_prefetch.py
39
41
  src/general_manager/api/graphql_relations.py
@@ -54,6 +56,8 @@ src/general_manager/api/remote_api.py
54
56
  src/general_manager/api/remote_invalidation.py
55
57
  src/general_manager/api/remote_invalidation_client.py
56
58
  src/general_manager/bucket/__init__.py
59
+ src/general_manager/bucket/_materialized_bucket.py
60
+ src/general_manager/bucket/_ordering.py
57
61
  src/general_manager/bucket/base_bucket.py
58
62
  src/general_manager/bucket/calculation_bucket.py
59
63
  src/general_manager/bucket/database_bucket.py
@@ -80,6 +84,7 @@ src/general_manager/chat/audit.py
80
84
  src/general_manager/chat/bootstrap.py
81
85
  src/general_manager/chat/checks.py
82
86
  src/general_manager/chat/consumer.py
87
+ src/general_manager/chat/context.py
83
88
  src/general_manager/chat/errors.py
84
89
  src/general_manager/chat/grounding.py
85
90
  src/general_manager/chat/models.py
@@ -240,6 +245,7 @@ src/general_manager/migrations/0008_upload_finalization_versions.py
240
245
  src/general_manager/migrations/0009_upload_cleanup_state.py
241
246
  src/general_manager/migrations/0010_chat_pending_confirmation_portable_uniqueness.py
242
247
  src/general_manager/migrations/0011_search_index_state_dirty_generation.py
248
+ src/general_manager/migrations/0012_chat_context_watermarks.py
243
249
  src/general_manager/migrations/__init__.py
244
250
  src/general_manager/permission/__init__.py
245
251
  src/general_manager/permission/audit.py
@@ -292,12 +298,13 @@ src/general_manager/uploads/types.py
292
298
  src/general_manager/uploads/urls.py
293
299
  src/general_manager/uploads/views.py
294
300
  src/general_manager/utils/__init__.py
295
- src/general_manager/utils/args_to_kwargs.py
301
+ src/general_manager/utils/_args_to_kwargs.py
302
+ src/general_manager/utils/_cache_key_encoder.py
303
+ src/general_manager/utils/_make_cache_key.py
304
+ src/general_manager/utils/_none_to_zero.py
296
305
  src/general_manager/utils/filter_parser.py
297
306
  src/general_manager/utils/format_string.py
298
307
  src/general_manager/utils/json_encoder.py
299
- src/general_manager/utils/make_cache_key.py
300
- src/general_manager/utils/none_to_zero.py
301
308
  src/general_manager/utils/path_mapping.py
302
309
  src/general_manager/utils/public_api.py
303
310
  src/general_manager/utils/testing.py
@@ -20,11 +20,11 @@ __all__ = [
20
20
  from general_manager.utils.json_encoder import CustomJSONEncoder
21
21
  from general_manager.utils.path_mapping import PathMap
22
22
  from general_manager.utils.filter_parser import UnknownInputFieldError
23
- from general_manager.utils.args_to_kwargs import args_to_kwargs
23
+ from general_manager.utils._args_to_kwargs import args_to_kwargs
24
24
  from general_manager.utils.format_string import camel_to_snake
25
25
  from general_manager.utils.filter_parser import create_filter_function
26
- from general_manager.utils.make_cache_key import make_cache_key
27
- from general_manager.utils.none_to_zero import none_to_zero
26
+ from general_manager.utils._make_cache_key import make_cache_key
27
+ from general_manager.utils._none_to_zero import none_to_zero
28
28
  from general_manager.utils.filter_parser import parse_filters
29
29
  from general_manager.utils.format_string import pascal_to_snake
30
30
  from general_manager.utils.format_string import snake_to_camel
@@ -101,7 +101,6 @@ from general_manager.api.graphql_output import (
101
101
  resolve_output_type_hints,
102
102
  )
103
103
  from general_manager.api.graphql_resolvers import (
104
- GraphQLSortInput,
105
104
  parse_input as _parse_input_fn,
106
105
  apply_query_parameters as _apply_query_parameters_fn,
107
106
  apply_permission_filters as _apply_permission_filters_fn,
@@ -115,6 +114,19 @@ from general_manager.api.graphql_resolvers import (
115
114
  create_resolver as _create_resolver_fn,
116
115
  resolve_with_read_permission as _resolve_with_read_permission_fn,
117
116
  )
117
+ from general_manager.api.graphql_ordering import (
118
+ OrderingTypes,
119
+ clear_ordering_type_cache,
120
+ create_ordering_types,
121
+ sortable_field_paths,
122
+ )
123
+ from general_manager.api.graphql_groups import (
124
+ create_group_resolver as _create_group_resolver_fn,
125
+ create_group_types as _create_group_types_fn,
126
+ create_member_resolver as _create_member_resolver_fn,
127
+ eligible_group_key_fields as _eligible_group_key_fields_fn,
128
+ group_sortable_field_paths as _group_sortable_field_paths_fn,
129
+ )
118
130
  from general_manager.api.graphql_relations import resolve_general_manager_type
119
131
  from general_manager.api.graphql_search import (
120
132
  register_search_query as _register_search_query_fn,
@@ -208,6 +220,17 @@ def _contains_graphql_output_type(
208
220
  )
209
221
 
210
222
 
223
+ def _contains_measurement(annotation: object) -> bool:
224
+ """Return whether an annotation contains a Measurement output value."""
225
+ if isinstance(annotation, ForwardRef):
226
+ annotation = annotation.__forward_arg__
227
+ if isinstance(annotation, str):
228
+ return annotation.strip("'\"") == "Measurement"
229
+ if safe_issubclass(annotation, Measurement):
230
+ return True
231
+ return any(_contains_measurement(argument) for argument in get_args(annotation))
232
+
233
+
211
234
  class GraphQLOutputTypeError(ValueError):
212
235
  """Raised when an output declaration cannot be registered safely."""
213
236
 
@@ -347,6 +370,7 @@ class GraphQL:
347
370
  _query_fields: ClassVar[GraphQLFieldMap] = {}
348
371
  _subscription_fields: ClassVar[GraphQLFieldMap] = {}
349
372
  _page_type_registry: ClassVar[dict[str, type[graphene.ObjectType]]] = {}
373
+ _group_page_type_registry: ClassVar[dict[str, type[graphene.ObjectType]]] = {}
350
374
  _subscription_payload_registry: ClassVar[dict[str, type[graphene.ObjectType]]] = {}
351
375
  graphql_type_registry: ClassVar[dict[str, type[graphene.ObjectType]]] = {}
352
376
  graphql_output_type_registry: ClassVar[dict[str, type[graphene.ObjectType]]] = {}
@@ -395,6 +419,7 @@ class GraphQL:
395
419
  cls._query_fields = {}
396
420
  cls._subscription_fields = {}
397
421
  cls._page_type_registry = {}
422
+ cls._group_page_type_registry = {}
398
423
  cls._subscription_payload_registry = {}
399
424
  cls.graphql_type_registry = {}
400
425
  cls.graphql_output_type_registry = {}
@@ -404,6 +429,7 @@ class GraphQL:
404
429
  cls._search_union = None
405
430
  cls._search_result_type = None
406
431
  cls._schema = None
432
+ clear_ordering_type_cache()
407
433
  from general_manager.chat.schema_index import clear_schema_index_cache
408
434
 
409
435
  clear_schema_index_cache()
@@ -433,6 +459,7 @@ class GraphQL:
433
459
  query_fields=dict(cls._query_fields),
434
460
  subscription_fields=dict(cls._subscription_fields),
435
461
  page_type_registry=dict(cls._page_type_registry),
462
+ group_page_type_registry=dict(cls._group_page_type_registry),
436
463
  subscription_payload_registry=dict(cls._subscription_payload_registry),
437
464
  graphql_type_registry=dict(cls.graphql_type_registry),
438
465
  graphql_output_type_registry=dict(cls.graphql_output_type_registry),
@@ -832,6 +859,62 @@ class GraphQL:
832
859
  field_name,
833
860
  resolved_field_type,
834
861
  )
862
+ if (
863
+ field_name.endswith("_list")
864
+ and resolved_manager_type is not None
865
+ and _eligible_group_key_fields_fn(resolved_manager_type)
866
+ ):
867
+ relation_manager_type = resolved_manager_type
868
+ group_field_name = f"{field_name.removesuffix('_list')}_groups"
869
+ group_arguments = cls._group_list_arguments(
870
+ relation_manager_type,
871
+ include_inactive=False,
872
+ scope="RelationGroups",
873
+ )
874
+ group_arguments["group_by"] = graphene.Argument(
875
+ graphene.List(graphene.NonNull(graphene.String)),
876
+ required=True,
877
+ )
878
+ member_arguments = cls._group_list_arguments(
879
+ relation_manager_type,
880
+ include_inactive=False,
881
+ scope="GroupMembers",
882
+ )
883
+ fields[group_field_name] = graphene.Field(
884
+ cls._get_or_create_group_page_type(
885
+ relation_manager_type,
886
+ member_arguments=member_arguments,
887
+ ),
888
+ **group_arguments,
889
+ )
890
+
891
+ def relation_group_base_getter(
892
+ instance: object,
893
+ _include_inactive: bool,
894
+ *,
895
+ _field_name: str = field_name,
896
+ ) -> Bucket[GeneralManager]:
897
+ return cast(
898
+ Bucket[GeneralManager],
899
+ getattr(instance, _field_name),
900
+ )
901
+
902
+ relation_group_page_resolver = _create_group_resolver_fn(
903
+ relation_group_base_getter,
904
+ relation_manager_type,
905
+ filter_normalizer=_normalize_filter_input_fn,
906
+ )
907
+
908
+ def relation_group_resolver(
909
+ manager_instance: GeneralManager,
910
+ info: GraphQLResolveInfo,
911
+ *,
912
+ _resolver: GraphQLResolver = relation_group_page_resolver,
913
+ **kwargs: object,
914
+ ) -> object:
915
+ return _resolver(manager_instance, info, **kwargs)
916
+
917
+ fields[f"resolve_{group_field_name}"] = relation_group_resolver
835
918
 
836
919
  output_classes = {
837
920
  output_class.__name__: output_class
@@ -845,6 +928,32 @@ class GraphQL:
845
928
  ) in generalManagerClass.Interface.get_graph_ql_properties().items():
846
929
  raw_hint = attr_value.graphql_type_hint
847
930
 
931
+ if _contains_measurement(raw_hint):
932
+ mapped = map_graphql_output_annotation(
933
+ raw_hint,
934
+ owner_name=generalManagerClass.__name__,
935
+ field_name=attr_name,
936
+ manager_registry=cls.manager_registry,
937
+ manager_type_registry=cls.graphql_type_registry,
938
+ output_class_registry=output_classes,
939
+ output_type_registry=cls.graphql_output_type_registry,
940
+ measurement_type=MeasurementType,
941
+ scalar_mapper=cls._map_field_to_graphene_base_type,
942
+ )
943
+ mapped_field = cast(graphene.Field, mapped.field)
944
+ mapped_type = mapped_field.type
945
+ if isinstance(mapped_type, graphene.NonNull):
946
+ mapped_type = mapped_type.of_type
947
+ fields[attr_name] = graphene.Field(
948
+ mapped_type,
949
+ target_unit=graphene.String(),
950
+ )
951
+ fields[f"resolve_{attr_name}"] = cls._create_resolver(
952
+ attr_name,
953
+ cast(type, mapped.resolver_type),
954
+ )
955
+ continue
956
+
848
957
  if _contains_graphql_output_type(raw_hint, output_classes):
849
958
  mapped = map_graphql_output_annotation(
850
959
  raw_hint,
@@ -1096,65 +1205,19 @@ class GraphQL:
1096
1205
  return provider_factory()
1097
1206
 
1098
1207
  @staticmethod
1099
- def _sort_by_options(
1208
+ def _ordering_types(
1100
1209
  generalManagerClass: type[GeneralManager],
1101
- ) -> type[graphene.Enum] | None:
1102
- """
1103
- Create a Graphene Enum of sortable field names for a GeneralManager subclass.
1104
-
1105
- Parameters:
1106
- generalManagerClass (type[GeneralManager]): The GeneralManager subclass to inspect for sortable attributes and GraphQL properties.
1107
-
1108
- Returns:
1109
- type[graphene.Enum] | None: A Graphene Enum type whose members are the sortable field names for the manager, or `None` if no sortable fields exist.
1110
- """
1111
- sort_options: dict[str, str] = {}
1112
- for (
1113
- field_name,
1114
- field_info,
1115
- ) in generalManagerClass.Interface.get_attribute_types().items():
1116
- field_type = field_info["type"]
1117
- related_manager = resolve_general_manager_type(
1118
- field_type, GraphQL.manager_registry
1119
- )
1120
- if related_manager is None:
1121
- sort_options[field_name] = field_name
1122
- continue
1123
- if field_info.get("relation_kind") == "collection":
1124
- continue
1125
-
1126
- sort_options[field_name] = f"{field_name}__id"
1127
- for (
1128
- related_name,
1129
- related_info,
1130
- ) in related_manager.Interface.get_attribute_types().items():
1131
- if related_info.get("relation_kind") == "collection":
1132
- continue
1133
- if (
1134
- resolve_general_manager_type(
1135
- related_info["type"], GraphQL.manager_registry
1136
- )
1137
- is not None
1138
- ):
1139
- continue
1140
- option_name = f"{field_name}__{related_name}"
1141
- sort_options[option_name] = option_name
1142
-
1143
- for (
1144
- prop_name,
1145
- prop,
1146
- ) in generalManagerClass.Interface.get_graph_ql_properties().items():
1147
- if prop.sortable is False:
1148
- continue
1149
- sort_options[prop_name] = prop_name
1150
-
1151
- if not sort_options:
1152
- return None
1153
-
1154
- return type(
1155
- f"{generalManagerClass.__name__}SortByOptions",
1156
- (graphene.Enum,),
1157
- sort_options,
1210
+ *,
1211
+ scope: str,
1212
+ ) -> OrderingTypes | None:
1213
+ """Build typed ordering inputs for one generated GraphQL scope."""
1214
+ return create_ordering_types(
1215
+ generalManagerClass,
1216
+ scope=scope,
1217
+ field_paths=sortable_field_paths(
1218
+ generalManagerClass,
1219
+ GraphQL.manager_registry,
1220
+ ),
1158
1221
  )
1159
1222
 
1160
1223
  @classmethod
@@ -1288,9 +1351,9 @@ class GraphQL:
1288
1351
  `Measurement` types map to the `MeasurementType` object wrapper with a
1289
1352
  `target_unit` argument. `GeneralManager` relations map to a single
1290
1353
  Graphene field, while relation fields whose name ends with `_list` map to
1291
- a paginated list field with `reverse`, `page`, `page_size`, `group_by`,
1292
- generated relation filter/exclude inputs when available, and `sort_by`
1293
- when sortable fields exist. Other types map through the scalar base
1354
+ a paginated list field with typed `order_by`, `page`, and `page_size`,
1355
+ plus generated relation filter/exclude inputs when available. Explicit
1356
+ sibling ``*_groups`` fields provide grouped results. Other types map through the scalar base
1294
1357
  mapper and may use `field_info["graphql_scalar"]` for supported scalar
1295
1358
  overrides such as `"bigint"`.
1296
1359
 
@@ -1318,20 +1381,18 @@ class GraphQL:
1318
1381
  elif safe_issubclass(field_type, GeneralManager):
1319
1382
  if field_name.endswith("_list"):
1320
1383
  attributes: GraphQLFieldMap = {
1321
- "reverse": graphene.Boolean(),
1322
1384
  "page": graphene.Int(),
1323
1385
  "page_size": graphene.Int(),
1324
- "group_by": graphene.List(graphene.String),
1325
1386
  }
1326
1387
  filter_options = GraphQL._create_filter_options(field_type)
1327
1388
  if filter_options:
1328
1389
  attributes["filter"] = graphene.Argument(filter_options)
1329
1390
  attributes["exclude"] = graphene.Argument(filter_options)
1330
1391
 
1331
- sort_by_options = GraphQL._sort_by_options(field_type)
1332
- if sort_by_options:
1333
- attributes["sort_by"] = graphene.Argument(
1334
- graphene.List(graphene.NonNull(sort_by_options))
1392
+ ordering_types = GraphQL._ordering_types(field_type, scope="Relation")
1393
+ if ordering_types:
1394
+ attributes["order_by"] = graphene.Argument(
1395
+ graphene.List(graphene.NonNull(ordering_types.input_type))
1335
1396
  )
1336
1397
 
1337
1398
  page_type = GraphQL._get_or_create_page_type(
@@ -1384,8 +1445,7 @@ class GraphQL:
1384
1445
  queryset: Bucket[GeneralManager],
1385
1446
  filter_input: GraphQLFilterInput,
1386
1447
  exclude_input: GraphQLFilterInput,
1387
- sort_by: GraphQLSortInput,
1388
- reverse: bool,
1448
+ order_by: object,
1389
1449
  filter_normalizer: GraphQLFilterNormalizer | None = None,
1390
1450
  ) -> Bucket[GeneralManager]:
1391
1451
  """Apply filter/exclude/sort to *queryset*. See ``graphql_resolvers.apply_query_parameters``."""
@@ -1393,8 +1453,7 @@ class GraphQL:
1393
1453
  queryset,
1394
1454
  filter_input,
1395
1455
  exclude_input,
1396
- sort_by,
1397
- reverse,
1456
+ order_by,
1398
1457
  filter_normalizer=filter_normalizer,
1399
1458
  )
1400
1459
 
@@ -1503,6 +1562,83 @@ class GraphQL:
1503
1562
  )
1504
1563
  return cls._page_type_registry[page_type_name]
1505
1564
 
1565
+ @classmethod
1566
+ def _group_list_arguments(
1567
+ cls,
1568
+ general_manager_class: type[GeneralManager],
1569
+ *,
1570
+ include_inactive: bool,
1571
+ scope: str,
1572
+ ) -> GraphQLFieldMap:
1573
+ """Build ordinary list controls shared by grouped pages and members."""
1574
+ arguments: GraphQLFieldMap = {
1575
+ "page": graphene.Int(),
1576
+ "page_size": graphene.Int(),
1577
+ }
1578
+ filter_options = cls._create_filter_options(general_manager_class)
1579
+ if filter_options:
1580
+ arguments["filter"] = graphene.Argument(filter_options)
1581
+ arguments["exclude"] = graphene.Argument(filter_options)
1582
+ ordering_types = (
1583
+ cls._group_ordering_types(general_manager_class, scope=scope)
1584
+ if scope in {"Groups", "RelationGroups"}
1585
+ else cls._ordering_types(general_manager_class, scope=scope)
1586
+ )
1587
+ if ordering_types:
1588
+ arguments["order_by"] = graphene.Argument(
1589
+ graphene.List(graphene.NonNull(ordering_types.input_type))
1590
+ )
1591
+ if include_inactive:
1592
+ arguments["include_inactive"] = graphene.Boolean()
1593
+ return arguments
1594
+
1595
+ @staticmethod
1596
+ def _group_ordering_types(
1597
+ general_manager_class: type[GeneralManager],
1598
+ *,
1599
+ scope: str,
1600
+ ) -> OrderingTypes | None:
1601
+ """Build order inputs from the same eligible keys accepted by groupBy."""
1602
+ return create_ordering_types(
1603
+ general_manager_class,
1604
+ scope=scope,
1605
+ field_paths=_group_sortable_field_paths_fn(
1606
+ general_manager_class,
1607
+ GraphQL.manager_registry,
1608
+ ),
1609
+ )
1610
+
1611
+ @classmethod
1612
+ def _get_or_create_group_page_type(
1613
+ cls,
1614
+ general_manager_class: type[GeneralManager],
1615
+ *,
1616
+ member_arguments: Mapping[str, object],
1617
+ ) -> type[graphene.ObjectType]:
1618
+ """Generate the typed explicit grouping result for one manager."""
1619
+ cached = cls._group_page_type_registry.get(general_manager_class.__name__)
1620
+ if cached is not None:
1621
+ return cached
1622
+ member_page_type = cls._get_or_create_page_type(
1623
+ general_manager_class.__name__ + "Page",
1624
+ lambda: cls.graphql_type_registry[general_manager_class.__name__],
1625
+ )
1626
+ member_resolver = _create_member_resolver_fn(
1627
+ general_manager_class,
1628
+ filter_normalizer=_normalize_filter_input_fn,
1629
+ )
1630
+ generated = _create_group_types_fn(
1631
+ general_manager_class,
1632
+ member_page_type=member_page_type,
1633
+ map_field=cls._map_field_to_graphene_read,
1634
+ member_resolver=member_resolver,
1635
+ member_arguments=member_arguments,
1636
+ )
1637
+ cls._group_page_type_registry[general_manager_class.__name__] = (
1638
+ generated.page_type
1639
+ )
1640
+ return generated.page_type
1641
+
1506
1642
  @classmethod
1507
1643
  def _build_identification_arguments(
1508
1644
  cls, generalManagerClass: type[GeneralManager]
@@ -1567,12 +1703,6 @@ class GraphQL:
1567
1703
  # resolver and field for the list query
1568
1704
  manager_field_name = pascal_to_snake(generalManagerClass.__name__)
1569
1705
  list_field_name = f"{manager_field_name}_list"
1570
- attributes: GraphQLFieldMap = {
1571
- "reverse": graphene.Boolean(),
1572
- "page": graphene.Int(),
1573
- "page_size": graphene.Int(),
1574
- "group_by": graphene.List(graphene.String),
1575
- }
1576
1706
  from general_manager.interface.capabilities.orm.support import (
1577
1707
  is_soft_delete_enabled,
1578
1708
  )
@@ -1582,17 +1712,12 @@ class GraphQL:
1582
1712
  type[OrmInterfaceBase[models.Model]],
1583
1713
  generalManagerClass.Interface,
1584
1714
  )
1585
- if is_soft_delete_enabled(interface_cls):
1586
- attributes["include_inactive"] = graphene.Boolean()
1587
- filter_options = cls._create_filter_options(generalManagerClass)
1588
- if filter_options:
1589
- attributes["filter"] = graphene.Argument(filter_options)
1590
- attributes["exclude"] = graphene.Argument(filter_options)
1591
- sort_by_options = cls._sort_by_options(generalManagerClass)
1592
- if sort_by_options:
1593
- attributes["sort_by"] = graphene.Argument(
1594
- graphene.List(graphene.NonNull(sort_by_options))
1595
- )
1715
+ supports_include_inactive = is_soft_delete_enabled(interface_cls)
1716
+ attributes = cls._group_list_arguments(
1717
+ generalManagerClass,
1718
+ include_inactive=supports_include_inactive,
1719
+ scope="",
1720
+ )
1596
1721
 
1597
1722
  page_type = cls._get_or_create_page_type(
1598
1723
  graphene_type.__name__ + "Page", graphene_type
@@ -1617,6 +1742,38 @@ class GraphQL:
1617
1742
  cls._query_fields[list_field_name] = list_field
1618
1743
  cls._query_fields[f"resolve_{list_field_name}"] = list_resolver
1619
1744
 
1745
+ if _eligible_group_key_fields_fn(generalManagerClass):
1746
+ group_field_name = f"{manager_field_name}_groups"
1747
+ group_arguments = cls._group_list_arguments(
1748
+ generalManagerClass,
1749
+ include_inactive=supports_include_inactive,
1750
+ scope="Groups",
1751
+ )
1752
+ group_arguments["group_by"] = graphene.Argument(
1753
+ graphene.List(graphene.NonNull(graphene.String)),
1754
+ required=True,
1755
+ )
1756
+ member_arguments = cls._group_list_arguments(
1757
+ generalManagerClass,
1758
+ include_inactive=False,
1759
+ scope="GroupMembers",
1760
+ )
1761
+ group_page_type = cls._get_or_create_group_page_type(
1762
+ generalManagerClass,
1763
+ member_arguments=member_arguments,
1764
+ )
1765
+ cls._query_fields[group_field_name] = graphene.Field(
1766
+ group_page_type,
1767
+ **group_arguments,
1768
+ )
1769
+ cls._query_fields[f"resolve_{group_field_name}"] = (
1770
+ _create_group_resolver_fn(
1771
+ _all_items,
1772
+ generalManagerClass,
1773
+ filter_normalizer=_normalize_filter_input_fn,
1774
+ )
1775
+ )
1776
+
1620
1777
  # resolver and field for the single item query
1621
1778
  item_field_name = manager_field_name
1622
1779
  identification_fields = cls._build_identification_arguments(generalManagerClass)
@@ -389,25 +389,24 @@ class PageInfo(ObjectType):
389
389
  generated page fields expose it, but callers should not import it directly.
390
390
 
391
391
  ``total_count`` is counted after permission filters, client filters, excludes,
392
- sorting, and grouping, but before slicing the current page. Out-of-range pages
393
- therefore return empty ``items`` with the same filtered ``total_count``.
392
+ sorting, and grouping, but before slicing the current page when the resolver
393
+ has a complete local result. It is ``None`` when a partial request response
394
+ cannot prove an authorized global total. Out-of-range pages therefore return
395
+ empty ``items`` with the same known filtered ``total_count``.
394
396
  ``current_page`` is 1-based and defaults to ``1`` when the client omits a
395
397
  page argument. ``page_size`` is nullable and remains ``None`` when no explicit
396
398
  page size was requested. ``total_pages`` is computed from ``page_size`` when
397
- present; without ``page_size`` it is ``1``, including empty result sets.
399
+ present; without ``page_size`` it is ``1`` for nonempty local results and
400
+ ``0`` for empty results. Unknown totals leave ``total_pages`` as ``None``.
398
401
  Pagination argument validation belongs to generated field/resolver code, not
399
- this metadata type. Generated fields currently add no validation beyond
400
- Graphene's integer coercion. Non-positive values are not normalized here.
401
- ``page_size=0`` behaves as omitted pagination for ``total_pages`` because it
402
- is falsy. Negative ``page_size`` or ``current_page`` values are passed to
403
- resolver slicing unchanged and should be treated as internal/legacy behavior
404
- rather than a public pagination contract.
402
+ this metadata type. Public list and search pagination require positive
403
+ integer values.
405
404
  """
406
405
 
407
- total_count = Int(required=True)
406
+ total_count = Int(required=False)
408
407
  page_size = Int(required=False)
409
408
  current_page = Int(required=True)
410
- total_pages = Int(required=True)
409
+ total_pages = Int(required=False)
411
410
 
412
411
 
413
412
  # ---------------------------------------------------------------------------