exobrain-database 0.1.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 (142) hide show
  1. exobrain_database-0.1.0/LICENSE.md +7 -0
  2. exobrain_database-0.1.0/PKG-INFO +166 -0
  3. exobrain_database-0.1.0/README.md +134 -0
  4. exobrain_database-0.1.0/pyproject.toml +115 -0
  5. exobrain_database-0.1.0/src/exobrain/database/__init__.py +0 -0
  6. exobrain_database-0.1.0/src/exobrain/database/migrations/README.md +1 -0
  7. exobrain_database-0.1.0/src/exobrain/database/migrations/__init__.py +9 -0
  8. exobrain_database-0.1.0/src/exobrain/database/migrations/alembic.ini +104 -0
  9. exobrain_database-0.1.0/src/exobrain/database/migrations/env.py +198 -0
  10. exobrain_database-0.1.0/src/exobrain/database/migrations/migration_manager.py +109 -0
  11. exobrain_database-0.1.0/src/exobrain/database/migrations/script.py.mako +47 -0
  12. exobrain_database-0.1.0/src/exobrain/database/migrations/versions/2023_08_17_0937-3ed3cf31c9d4_.py +161 -0
  13. exobrain_database-0.1.0/src/exobrain/database/migrations/versions/2023_08_31_1322-aa6854636eac_.py +181 -0
  14. exobrain_database-0.1.0/src/exobrain/database/migrations/versions/2023_09_01_0925-9667f0608380_.py +108 -0
  15. exobrain_database-0.1.0/src/exobrain/database/migrations/versions/2023_09_13_1243-3cd1eb0d7b52_.py +238 -0
  16. exobrain_database-0.1.0/src/exobrain/database/migrations/versions/2023_09_15_1447-52f33bc03521_.py +72 -0
  17. exobrain_database-0.1.0/src/exobrain/database/migrations/versions/2023_09_19_0956-f8e096a41120_.py +70 -0
  18. exobrain_database-0.1.0/src/exobrain/database/migrations/versions/2023_09_21_1642-74f18c0bab6e_.py +548 -0
  19. exobrain_database-0.1.0/src/exobrain/database/migrations/versions/2023_09_28_1237-919ce06afab1_.py +71 -0
  20. exobrain_database-0.1.0/src/exobrain/database/migrations/versions/2023_10_04_0718-03535f8dfe5f_.py +150 -0
  21. exobrain_database-0.1.0/src/exobrain/database/migrations/versions/2023_10_05_1508-f64d4c00b610_.py +284 -0
  22. exobrain_database-0.1.0/src/exobrain/database/migrations/versions/2023_10_06_0819-e544518a415c_.py +273 -0
  23. exobrain_database-0.1.0/src/exobrain/database/migrations/versions/2023_10_06_1312-b9b232d63be3_.py +70 -0
  24. exobrain_database-0.1.0/src/exobrain/database/migrations/versions/2023_10_25_0902-aab08fb68941_.py +70 -0
  25. exobrain_database-0.1.0/src/exobrain/database/migrations/versions/2023_10_25_0937-d59ec80e6dd7_.py +68 -0
  26. exobrain_database-0.1.0/src/exobrain/database/migrations/versions/2023_11_22_1628-84b116f3df26_.py +84 -0
  27. exobrain_database-0.1.0/src/exobrain/database/migrations/versions/2023_11_22_1654-bcb01e365c42_.py +102 -0
  28. exobrain_database-0.1.0/src/exobrain/database/migrations/versions/2023_11_27_1045-00ce519af235_.py +70 -0
  29. exobrain_database-0.1.0/src/exobrain/database/migrations/versions/2023_11_27_1048-f779dc9fe429_.py +70 -0
  30. exobrain_database-0.1.0/src/exobrain/database/migrations/versions/2023_11_29_1421-ad2b4c9c38fe_.py +68 -0
  31. exobrain_database-0.1.0/src/exobrain/database/migrations/versions/2023_12_04_1029-f91d936478fb_.py +70 -0
  32. exobrain_database-0.1.0/src/exobrain/database/migrations/versions/2023_12_11_1104-b33e0d6a5bdd_.py +71 -0
  33. exobrain_database-0.1.0/src/exobrain/database/migrations/versions/2023_12_18_1406-73ac94585923_.py +70 -0
  34. exobrain_database-0.1.0/src/exobrain/database/migrations/versions/2024_01_05_1022-f231770c573e_.py +83 -0
  35. exobrain_database-0.1.0/src/exobrain/database/migrations/versions/2024_01_17_1606-b94c145b2310_.py +70 -0
  36. exobrain_database-0.1.0/src/exobrain/database/migrations/versions/2024_01_18_1547-c450c961dfd0_.py +79 -0
  37. exobrain_database-0.1.0/src/exobrain/database/migrations/versions/2024_01_18_1855-7101980bc238_.py +86 -0
  38. exobrain_database-0.1.0/src/exobrain/database/migrations/versions/2024_01_22_1616-a35a2828dbcd_.py +75 -0
  39. exobrain_database-0.1.0/src/exobrain/database/migrations/versions/2024_03_04_1549-4cc4ffdb6c02_.py +70 -0
  40. exobrain_database-0.1.0/src/exobrain/database/migrations/versions/2024_03_13_1323-97a9ef3f38c3_.py +151 -0
  41. exobrain_database-0.1.0/src/exobrain/database/migrations/versions/2024_03_20_1033-13bc4d2ab3ab_.py +96 -0
  42. exobrain_database-0.1.0/src/exobrain/database/migrations/versions/2024_03_28_0905-ffd01ebb2c87_.py +71 -0
  43. exobrain_database-0.1.0/src/exobrain/database/migrations/versions/2024_03_28_1332-33744d8620d3_.py +144 -0
  44. exobrain_database-0.1.0/src/exobrain/database/migrations/versions/2024_04_05_0919-a14d98908583_.py +88 -0
  45. exobrain_database-0.1.0/src/exobrain/database/migrations/versions/2024_04_29_1515-882409414d37_.py +84 -0
  46. exobrain_database-0.1.0/src/exobrain/database/migrations/versions/2024_05_23_0959-24bb8fdb3ba7_.py +72 -0
  47. exobrain_database-0.1.0/src/exobrain/database/migrations/versions/2024_05_24_1248-f2a78a625a74_.py +82 -0
  48. exobrain_database-0.1.0/src/exobrain/database/migrations/versions/2024_06_07_1537-004b611f77cf_.py +297 -0
  49. exobrain_database-0.1.0/src/exobrain/database/migrations/versions/2024_06_10_1306-f0fe99d57963_.py +76 -0
  50. exobrain_database-0.1.0/src/exobrain/database/migrations/versions/2024_10_15_0646-ef0829fe3540_.py +70 -0
  51. exobrain_database-0.1.0/src/exobrain/database/migrations/versions/2025_01_28_1020-ea2ebd0e2cdc_.py +126 -0
  52. exobrain_database-0.1.0/src/exobrain/database/migrations/versions/2025_03_19_1341-adeeb7c46a3c_.py +112 -0
  53. exobrain_database-0.1.0/src/exobrain/database/migrations/versions/2025_03_25_1449-8fb5b2059d5a_.py +78 -0
  54. exobrain_database-0.1.0/src/exobrain/database/migrations/versions/2025_05_06_1503-88aa2ef323c5-org.json +338 -0
  55. exobrain_database-0.1.0/src/exobrain/database/migrations/versions/2025_05_06_1503-88aa2ef323c5-public.json +464 -0
  56. exobrain_database-0.1.0/src/exobrain/database/migrations/versions/2025_05_06_1503-88aa2ef323c5_add_constraints_to_fk.py +82 -0
  57. exobrain_database-0.1.0/src/exobrain/database/migrations/versions/2025_05_20_1302-37f7dbf56615_add_is_learning_field_to_license.py +67 -0
  58. exobrain_database-0.1.0/src/exobrain/database/migrations/versions/2025_05_21_0839-096c1ab6ea15_add_is_learning_field_to_predefined_.py +67 -0
  59. exobrain_database-0.1.0/src/exobrain/database/migrations/versions/2025_06_03_0336-60d91382b626_add_grace_period_field_to_risk_conf.py +71 -0
  60. exobrain_database-0.1.0/src/exobrain/database/migrations/versions/2025_06_17_1013-4894e248a31d_add_risk_conf_buffer_period_field_to_.py +76 -0
  61. exobrain_database-0.1.0/src/exobrain/database/migrations/versions/2025_06_20_0845-c0e0c905cfb1_add_computing_strategy.py +89 -0
  62. exobrain_database-0.1.0/src/exobrain/database/migrations/versions/2025_06_20_0919-360b6879ae25_add_fully_computed_field_to_running_.py +71 -0
  63. exobrain_database-0.1.0/src/exobrain/database/migrations/versions/2025_06_21_1200-1a37475a962d_fix_feasible_field_in_running_risk_table_set_not_null.py +76 -0
  64. exobrain_database-0.1.0/src/exobrain/database/migrations/versions/2025_06_21_1300-d456be82025a_add_computed_mapping_field_in_running_.py +85 -0
  65. exobrain_database-0.1.0/src/exobrain/database/migrations/versions/2025_06_27_0154-317d388748a1_adding_auto_rejected_reason_code.py +112 -0
  66. exobrain_database-0.1.0/src/exobrain/database/migrations/versions/2025_06_27_0227-0a9522eb04f0_update_predefined_actions_execution.py +183 -0
  67. exobrain_database-0.1.0/src/exobrain/database/migrations/versions/2025_06_27_0610-9daee7d935b1_add_rejection_and_expiration_fields.py +153 -0
  68. exobrain_database-0.1.0/src/exobrain/database/migrations/versions/2025_06_27_0617-ee6062e6dc4d_add_rejection_and_expiration_fields.py +205 -0
  69. exobrain_database-0.1.0/src/exobrain/database/migrations/versions/2025_06_29_0828-90923eeab038_calculate_due_dates_and_due_indicators.py +133 -0
  70. exobrain_database-0.1.0/src/exobrain/database/migrations/versions/2025_09_26_1624-2716d77c7904_make_context_fields_non_nullable.py +244 -0
  71. exobrain_database-0.1.0/src/exobrain/database/migrations/versions/2025_09_26_1857-0ab6e7d1a127_add_note_column_to_running_action.py +34 -0
  72. exobrain_database-0.1.0/src/exobrain/database/migrations/versions/2025_10_17_1620-6400ea4ce6f0_add_index_overdue_risks.py +55 -0
  73. exobrain_database-0.1.0/src/exobrain/database/migrations/versions/2025_10_31_0222-67c46f78caca_convert_action_context_data_json_to_jsonb.py +71 -0
  74. exobrain_database-0.1.0/src/exobrain/database/migrations/versions/2025_11_04_2117-a8a814d7f2ea_rename_execution_reason_code.py +55 -0
  75. exobrain_database-0.1.0/src/exobrain/database/migrations/versions/2026_01_04_1647-87c0d5fd2688_apply_new_naming_rules_for_indexes.py +50 -0
  76. exobrain_database-0.1.0/src/exobrain/database/migrations/versions/2026_01_04_1801-392b727bbaa1_remove_unused_exo_conf_table.py +96 -0
  77. exobrain_database-0.1.0/src/exobrain/database/migrations/versions/2026_01_05_0840-4b12100a932c_add_constraints_to_organizations_settings.py +117 -0
  78. exobrain_database-0.1.0/src/exobrain/database/migrations/versions/2026_01_05_0917-f67bd91a1913_change_copilot_uiConfiguration_json_to_jsonb.py +54 -0
  79. exobrain_database-0.1.0/src/exobrain/database/migrations/versions/2026_01_05_0935-87de8335f045_constrain_organizations_preferences_fields.py +140 -0
  80. exobrain_database-0.1.0/src/exobrain/database/migrations/versions/2026_01_05_1018-7271b6d49e2c_enforce_not_null_and_jsonb_for_predefined_tables.py +264 -0
  81. exobrain_database-0.1.0/src/exobrain/database/migrations/versions/2026_01_05_1510-711567521aa6_convert_config_tables_json_to_jsonb.py +91 -0
  82. exobrain_database-0.1.0/src/exobrain/database/migrations/versions/2026_01_05_1540-ce5a35090a82_convert_connection_json_to_jsonb.py +60 -0
  83. exobrain_database-0.1.0/src/exobrain/database/migrations/versions/2026_01_06_0939-115812c0bcd6_make_scope_key_non_nullable.py +52 -0
  84. exobrain_database-0.1.0/src/exobrain/database/migrations/versions/2026_01_06_1109-7dd6b5f271ed_convert_json_to_jsonb_for_dashboard_and_widgets.py +77 -0
  85. exobrain_database-0.1.0/src/exobrain/database/migrations/versions/2026_01_06_1452-4e4ad858fdf9_convert_json_to_jsonb_for_running_entities.py +185 -0
  86. exobrain_database-0.1.0/src/exobrain/database/migrations/versions/2026_01_09_1558-6954766729aa_simplify_one_to_many_relationships.py +72 -0
  87. exobrain_database-0.1.0/src/exobrain/database/migrations/versions/2026_01_12_1639-e548f437e5de_simplify_one_to_many_relationships.py +266 -0
  88. exobrain_database-0.1.0/src/exobrain/database/migrations/versions/2026_02_03_1456-abbb5a630567_simplify_one_to_many_relationships.py +285 -0
  89. exobrain_database-0.1.0/src/exobrain/database/migrations/versions/2026_02_06_0827-95438a5ec210_simplify_one_to_many_relationships.py +85 -0
  90. exobrain_database-0.1.0/src/exobrain/database/migrations/versions/2026_02_06_0835-881f104f8b2b_simplify_one_to_many_relationships.py +432 -0
  91. exobrain_database-0.1.0/src/exobrain/database/migrations/versions/2026_04_20_1015-8f3c5e2d9a1b_add_running_action_summary_table_with_text_column.py +48 -0
  92. exobrain_database-0.1.0/src/exobrain/database/migrations/versions/2026_04_30_1357-c3e8047f29f6_add_kpi_names_to_predefined_action.py +44 -0
  93. exobrain_database-0.1.0/src/exobrain/database/migrations/versions/2026_05_07_0100-a1b2c3d4e5f6_create_scores_table.py +53 -0
  94. exobrain_database-0.1.0/src/exobrain/database/model/__init__.py +4 -0
  95. exobrain_database-0.1.0/src/exobrain/database/model/associations/__init__.py +41 -0
  96. exobrain_database-0.1.0/src/exobrain/database/model/associations/action_conf_action_reason.py +20 -0
  97. exobrain_database-0.1.0/src/exobrain/database/model/associations/copilot_license.py +20 -0
  98. exobrain_database-0.1.0/src/exobrain/database/model/associations/exec_conf_execution_reason.py +19 -0
  99. exobrain_database-0.1.0/src/exobrain/database/model/associations/predefined_action_action_reason.py +20 -0
  100. exobrain_database-0.1.0/src/exobrain/database/model/associations/predefined_action_predefined_risk.py +20 -0
  101. exobrain_database-0.1.0/src/exobrain/database/model/associations/predefined_execution_execution_reason.py +20 -0
  102. exobrain_database-0.1.0/src/exobrain/database/model/associations/predefined_execution_predefined_action.py +20 -0
  103. exobrain_database-0.1.0/src/exobrain/database/model/associations/predefined_risk_risk_reason.py +20 -0
  104. exobrain_database-0.1.0/src/exobrain/database/model/associations/risk_conf_risk_reason.py +19 -0
  105. exobrain_database-0.1.0/src/exobrain/database/model/associations/roles_action_conf.py +19 -0
  106. exobrain_database-0.1.0/src/exobrain/database/model/associations/roles_exec_conf.py +19 -0
  107. exobrain_database-0.1.0/src/exobrain/database/model/associations/roles_permissions.py +20 -0
  108. exobrain_database-0.1.0/src/exobrain/database/model/associations/roles_predefined_action.py +20 -0
  109. exobrain_database-0.1.0/src/exobrain/database/model/associations/roles_predefined_execution.py +20 -0
  110. exobrain_database-0.1.0/src/exobrain/database/model/associations/roles_running_actions.py +19 -0
  111. exobrain_database-0.1.0/src/exobrain/database/model/associations/roles_running_executions.py +19 -0
  112. exobrain_database-0.1.0/src/exobrain/database/model/associations/roles_users.py +19 -0
  113. exobrain_database-0.1.0/src/exobrain/database/model/associations/running_action_context_scopes.py +19 -0
  114. exobrain_database-0.1.0/src/exobrain/database/model/associations/users_scopes.py +19 -0
  115. exobrain_database-0.1.0/src/exobrain/database/model/base.py +46 -0
  116. exobrain_database-0.1.0/src/exobrain/database/model/enums/__init__.py +13 -0
  117. exobrain_database-0.1.0/src/exobrain/database/model/enums/config.py +30 -0
  118. exobrain_database-0.1.0/src/exobrain/database/model/enums/currency.py +178 -0
  119. exobrain_database-0.1.0/src/exobrain/database/model/enums/running.py +87 -0
  120. exobrain_database-0.1.0/src/exobrain/database/model/field_types.py +6 -0
  121. exobrain_database-0.1.0/src/exobrain/database/model/general/__init__.py +23 -0
  122. exobrain_database-0.1.0/src/exobrain/database/model/general/copilot.py +50 -0
  123. exobrain_database-0.1.0/src/exobrain/database/model/general/general_base.py +31 -0
  124. exobrain_database-0.1.0/src/exobrain/database/model/general/organization_models.py +91 -0
  125. exobrain_database-0.1.0/src/exobrain/database/model/general/permission.py +33 -0
  126. exobrain_database-0.1.0/src/exobrain/database/model/general/predefined_models.py +225 -0
  127. exobrain_database-0.1.0/src/exobrain/database/model/general/reason_models.py +147 -0
  128. exobrain_database-0.1.0/src/exobrain/database/model/general/role.py +96 -0
  129. exobrain_database-0.1.0/src/exobrain/database/model/org/__init__.py +43 -0
  130. exobrain_database-0.1.0/src/exobrain/database/model/org/config_models.py +293 -0
  131. exobrain_database-0.1.0/src/exobrain/database/model/org/connection.py +22 -0
  132. exobrain_database-0.1.0/src/exobrain/database/model/org/dashboard_models.py +84 -0
  133. exobrain_database-0.1.0/src/exobrain/database/model/org/org_base.py +31 -0
  134. exobrain_database-0.1.0/src/exobrain/database/model/org/organization_settings.py +55 -0
  135. exobrain_database-0.1.0/src/exobrain/database/model/org/running_models.py +778 -0
  136. exobrain_database-0.1.0/src/exobrain/database/model/org/scope.py +51 -0
  137. exobrain_database-0.1.0/src/exobrain/database/model/org/user.py +53 -0
  138. exobrain_database-0.1.0/src/exobrain/database/py.typed +0 -0
  139. exobrain_database-0.1.0/src/exobrain/database/tools/__init__.py +0 -0
  140. exobrain_database-0.1.0/src/exobrain/database/tools/jsonb_filter.py +369 -0
  141. exobrain_database-0.1.0/src/exobrain/database/tools/record_count.py +60 -0
  142. exobrain_database-0.1.0/src/exobrain/database/tools/sql_query_logger.py +83 -0
@@ -0,0 +1,7 @@
1
+ Copyright © 2025-present DFYA SAS, All rights reserved.
2
+
3
+ This is a private project.
4
+ All rights reserved.
5
+
6
+ The content of this repository is intended for private use only.
7
+ Reproduction, distribution, or disclosure to third parties, in whole or in part, is strictly prohibited without the explicit written permission of the copyright holder.
@@ -0,0 +1,166 @@
1
+ Metadata-Version: 2.3
2
+ Name: exobrain-database
3
+ Version: 0.1.0
4
+ Summary: Exobrain database model and migration management
5
+ Keywords:
6
+ Author: Laurent LAPORTE
7
+ Author-email: Laurent LAPORTE <laurent@dfya.io>
8
+ License: Copyright © 2025-present DFYA SAS, All rights reserved.
9
+
10
+ This is a private project.
11
+ All rights reserved.
12
+
13
+ The content of this repository is intended for private use only.
14
+ Reproduction, distribution, or disclosure to third parties, in whole or in part, is strictly prohibited without the explicit written permission of the copyright holder.
15
+ Classifier: Development Status :: 4 - Beta
16
+ Classifier: Programming Language :: Python
17
+ Classifier: Programming Language :: Python :: 3.12
18
+ Classifier: Programming Language :: Python :: 3.13
19
+ Classifier: Programming Language :: Python :: 3.14
20
+ Classifier: Topic :: Software Development :: Libraries
21
+ Classifier: Topic :: Database
22
+ Classifier: Topic :: Database :: Database Engines/Servers
23
+ Classifier: License :: Other/Proprietary License
24
+ Requires-Dist: alembic~=1.18.4
25
+ Requires-Dist: psycopg[binary]~=3.3.4
26
+ Requires-Dist: sqlalchemy~=2.0.51
27
+ Requires-Python: >=3.12
28
+ Project-URL: Documentation, https://github.com/MyExobrain/exobrain-database#readme
29
+ Project-URL: Issues, https://github.com/MyExobrain/exobrain-database/issues
30
+ Project-URL: Source, https://github.com/MyExobrain/exobrain-database
31
+ Description-Content-Type: text/markdown
32
+
33
+ # exobrain-database
34
+
35
+ [![PyPI - Version](https://img.shields.io/pypi/v/exobrain-database.svg)](https://pypi.org/project/exobrain-database)
36
+ [![PyPI - Python Version](https://img.shields.io/pypi/pyversions/exobrain-database.svg)](https://pypi.org/project/exobrain-database)
37
+ [![CI/CD](https://github.com/MyExobrain/exobrain-database/actions/workflows/build.yml/badge.svg)](https://github.com/MyExobrain/exobrain-database/actions/workflows/build.yml)
38
+
39
+ ---
40
+
41
+ `exobrain-database` is a Python library that provides the SQLAlchemy ORM models, Alembic migration management,
42
+ and utility tools for the Exobrain platform database. It supports a **multi-tenant architecture** where each
43
+ organization has its own isolated PostgreSQL schema.
44
+
45
+ The package is distributed as a **namespace package** under `exobrain.database`, making it composable with
46
+ other `exobrain.*` packages.
47
+
48
+ ---
49
+
50
+ ## Table of Contents
51
+
52
+ - [Installation](#installation)
53
+ - [Development](#development)
54
+ - [Project Structure](#project-structure)
55
+ - [Usage](#usage)
56
+ - [License](#license)
57
+
58
+ ---
59
+
60
+ ## Installation
61
+
62
+ ```console
63
+ pip install exobrain-database
64
+ ```
65
+
66
+ Or with [uv](https://docs.astral.sh/uv/):
67
+
68
+ ```console
69
+ uv add exobrain-database
70
+ ```
71
+
72
+ ---
73
+
74
+ ## Development
75
+
76
+ This project uses [uv](https://docs.astral.sh/uv/) for dependency management and building.
77
+
78
+ **Prerequisites:** Python 3.12+ and uv
79
+
80
+ Setup:
81
+ ```console
82
+ git clone git@github.com:MyExobrain/exobrain-database.git
83
+ cd exobrain-database
84
+ uv sync --all-groups
85
+ ```
86
+
87
+ Common tasks:
88
+ ```console
89
+ uv run pytest # Run tests
90
+ uv run pytest --cov=exobrain.database # Tests with coverage
91
+ uv run ruff check src tests # Lint
92
+ uv run ruff format src tests # Format
93
+ uv run mypy src # Type check
94
+ uv build # Build wheel + sdist
95
+ ```
96
+
97
+ Add dependencies:
98
+ ```console
99
+ uv add package-name # Production
100
+ uv add --group dev package-name # Development
101
+ uv sync --upgrade # Update all
102
+ ```
103
+
104
+ ---
105
+
106
+ ## Project Structure
107
+
108
+ The source code lives under `src/exobrain/database/` as a namespace package:
109
+
110
+ ```
111
+ src/exobrain/database/
112
+ ├── migrations/ # Alembic migration engine
113
+ │ ├── alembic.ini # Alembic configuration file
114
+ │ ├── env.py # Migration environment setup
115
+ │ ├── migration_manager.py # Public API: upgrade / downgrade per org schema
116
+ │ └── versions/ # Auto-generated migration scripts
117
+ ├── model/ # SQLAlchemy ORM models
118
+ │ ├── base.py # Declarative base classes
119
+ │ ├── associations/ # Many-to-many association tables
120
+ │ ├── enums/ # Database enumeration types (config, currency, running states)
121
+ │ ├── general/ # Cross-organization models (copilots, permissions, roles,
122
+ │ │ # predefined actions/executions/risks, reasons)
123
+ │ └── org/ # Per-organization models (config, connections, dashboards,
124
+ │ # running actions/executions/risks, scopes, users)
125
+ └── tools/ # Reusable database utilities
126
+ ├── jsonb_filter.py # Helper for filtering on JSONB columns
127
+ ├── record_count.py # Efficient record counting queries
128
+ └── sql_query_logger.py # SQLAlchemy query logging utility
129
+ ```
130
+
131
+ ### Key design decisions
132
+
133
+ - **Multi-tenant schemas**: each organization's data is isolated in a dedicated PostgreSQL schema
134
+ (e.g. `org_<id>`). Migrations are applied per-schema via `migration_manager.upgrade(org_id)`.
135
+ - **Namespace package**: `exobrain.database` has no `__init__.py` at the `exobrain` level, allowing
136
+ other `exobrain.*` packages to coexist in the same Python environment.
137
+ - **`py.typed` marker**: the package ships type information and is fully typed (compatible with mypy
138
+ in strict mode).
139
+ - **Build system**: Uses `uv` as the modern Python build & package manager.
140
+
141
+ ---
142
+
143
+ ## Usage
144
+
145
+ ### Apply migrations for an organization
146
+
147
+ ```python
148
+ from uuid import UUID
149
+ from exobrain.database.migrations import migration_manager
150
+
151
+ org_id = UUID("12345678-1234-5678-1234-567812345678")
152
+ migration_manager.upgrade(org_id)
153
+ ```
154
+
155
+ ### Use ORM models
156
+
157
+ ```python
158
+ from exobrain.database.model.general.role import Role
159
+ from exobrain.database.model.org.user import User
160
+ ```
161
+
162
+ ---
163
+
164
+ ## License
165
+
166
+ `exobrain-database` is distributed under a proprietary license. See [LICENSE.md](LICENSE.md) for details.
@@ -0,0 +1,134 @@
1
+ # exobrain-database
2
+
3
+ [![PyPI - Version](https://img.shields.io/pypi/v/exobrain-database.svg)](https://pypi.org/project/exobrain-database)
4
+ [![PyPI - Python Version](https://img.shields.io/pypi/pyversions/exobrain-database.svg)](https://pypi.org/project/exobrain-database)
5
+ [![CI/CD](https://github.com/MyExobrain/exobrain-database/actions/workflows/build.yml/badge.svg)](https://github.com/MyExobrain/exobrain-database/actions/workflows/build.yml)
6
+
7
+ ---
8
+
9
+ `exobrain-database` is a Python library that provides the SQLAlchemy ORM models, Alembic migration management,
10
+ and utility tools for the Exobrain platform database. It supports a **multi-tenant architecture** where each
11
+ organization has its own isolated PostgreSQL schema.
12
+
13
+ The package is distributed as a **namespace package** under `exobrain.database`, making it composable with
14
+ other `exobrain.*` packages.
15
+
16
+ ---
17
+
18
+ ## Table of Contents
19
+
20
+ - [Installation](#installation)
21
+ - [Development](#development)
22
+ - [Project Structure](#project-structure)
23
+ - [Usage](#usage)
24
+ - [License](#license)
25
+
26
+ ---
27
+
28
+ ## Installation
29
+
30
+ ```console
31
+ pip install exobrain-database
32
+ ```
33
+
34
+ Or with [uv](https://docs.astral.sh/uv/):
35
+
36
+ ```console
37
+ uv add exobrain-database
38
+ ```
39
+
40
+ ---
41
+
42
+ ## Development
43
+
44
+ This project uses [uv](https://docs.astral.sh/uv/) for dependency management and building.
45
+
46
+ **Prerequisites:** Python 3.12+ and uv
47
+
48
+ Setup:
49
+ ```console
50
+ git clone git@github.com:MyExobrain/exobrain-database.git
51
+ cd exobrain-database
52
+ uv sync --all-groups
53
+ ```
54
+
55
+ Common tasks:
56
+ ```console
57
+ uv run pytest # Run tests
58
+ uv run pytest --cov=exobrain.database # Tests with coverage
59
+ uv run ruff check src tests # Lint
60
+ uv run ruff format src tests # Format
61
+ uv run mypy src # Type check
62
+ uv build # Build wheel + sdist
63
+ ```
64
+
65
+ Add dependencies:
66
+ ```console
67
+ uv add package-name # Production
68
+ uv add --group dev package-name # Development
69
+ uv sync --upgrade # Update all
70
+ ```
71
+
72
+ ---
73
+
74
+ ## Project Structure
75
+
76
+ The source code lives under `src/exobrain/database/` as a namespace package:
77
+
78
+ ```
79
+ src/exobrain/database/
80
+ ├── migrations/ # Alembic migration engine
81
+ │ ├── alembic.ini # Alembic configuration file
82
+ │ ├── env.py # Migration environment setup
83
+ │ ├── migration_manager.py # Public API: upgrade / downgrade per org schema
84
+ │ └── versions/ # Auto-generated migration scripts
85
+ ├── model/ # SQLAlchemy ORM models
86
+ │ ├── base.py # Declarative base classes
87
+ │ ├── associations/ # Many-to-many association tables
88
+ │ ├── enums/ # Database enumeration types (config, currency, running states)
89
+ │ ├── general/ # Cross-organization models (copilots, permissions, roles,
90
+ │ │ # predefined actions/executions/risks, reasons)
91
+ │ └── org/ # Per-organization models (config, connections, dashboards,
92
+ │ # running actions/executions/risks, scopes, users)
93
+ └── tools/ # Reusable database utilities
94
+ ├── jsonb_filter.py # Helper for filtering on JSONB columns
95
+ ├── record_count.py # Efficient record counting queries
96
+ └── sql_query_logger.py # SQLAlchemy query logging utility
97
+ ```
98
+
99
+ ### Key design decisions
100
+
101
+ - **Multi-tenant schemas**: each organization's data is isolated in a dedicated PostgreSQL schema
102
+ (e.g. `org_<id>`). Migrations are applied per-schema via `migration_manager.upgrade(org_id)`.
103
+ - **Namespace package**: `exobrain.database` has no `__init__.py` at the `exobrain` level, allowing
104
+ other `exobrain.*` packages to coexist in the same Python environment.
105
+ - **`py.typed` marker**: the package ships type information and is fully typed (compatible with mypy
106
+ in strict mode).
107
+ - **Build system**: Uses `uv` as the modern Python build & package manager.
108
+
109
+ ---
110
+
111
+ ## Usage
112
+
113
+ ### Apply migrations for an organization
114
+
115
+ ```python
116
+ from uuid import UUID
117
+ from exobrain.database.migrations import migration_manager
118
+
119
+ org_id = UUID("12345678-1234-5678-1234-567812345678")
120
+ migration_manager.upgrade(org_id)
121
+ ```
122
+
123
+ ### Use ORM models
124
+
125
+ ```python
126
+ from exobrain.database.model.general.role import Role
127
+ from exobrain.database.model.org.user import User
128
+ ```
129
+
130
+ ---
131
+
132
+ ## License
133
+
134
+ `exobrain-database` is distributed under a proprietary license. See [LICENSE.md](LICENSE.md) for details.
@@ -0,0 +1,115 @@
1
+ [build-system]
2
+ requires = ["uv_build>=0.11.23,<0.12"]
3
+ build-backend = "uv_build"
4
+
5
+ [project]
6
+ name = "exobrain-database"
7
+ version = "0.1.0"
8
+ description = "Exobrain database model and migration management"
9
+ authors = [
10
+ { name = "Laurent LAPORTE", email = "laurent@dfya.io" }
11
+ ]
12
+ readme = "README.md"
13
+ requires-python = ">=3.12"
14
+ license = { file = "LICENSE.md" }
15
+ keywords = []
16
+ classifiers = [
17
+ "Development Status :: 4 - Beta",
18
+ "Programming Language :: Python",
19
+ "Programming Language :: Python :: 3.12",
20
+ "Programming Language :: Python :: 3.13",
21
+ "Programming Language :: Python :: 3.14",
22
+ "Topic :: Software Development :: Libraries",
23
+ "Topic :: Database",
24
+ "Topic :: Database :: Database Engines/Servers",
25
+ "License :: Other/Proprietary License",
26
+ ]
27
+ dependencies = [
28
+ "alembic~=1.18.4",
29
+ "psycopg[binary]~=3.3.4",
30
+ "sqlalchemy~=2.0.51",
31
+ ]
32
+
33
+ [project.urls]
34
+ Documentation = "https://github.com/MyExobrain/exobrain-database#readme"
35
+ Issues = "https://github.com/MyExobrain/exobrain-database/issues"
36
+ Source = "https://github.com/MyExobrain/exobrain-database"
37
+
38
+ [dependency-groups]
39
+ dev = [
40
+ "coverage~=7.14.2",
41
+ "mypy~=2.1.0",
42
+ "pytest~=9.1.1",
43
+ "pytest-cov~=7.1.0",
44
+ "twine~=6.2.0",
45
+ ]
46
+
47
+ # -----------------------------------------------
48
+ # Configuration for "uv" build tool
49
+ # -----------------------------------------------
50
+
51
+ [tool.uv.build-backend]
52
+ module-name = "exobrain.database"
53
+
54
+ # -----------------------------------------------
55
+ # Configuration for "coverage" tool (testing coverage)
56
+ # -----------------------------------------------
57
+
58
+ [tool.coverage.run]
59
+ source_pkgs = ["exobrain.database", "tests"]
60
+ branch = true
61
+ parallel = true
62
+
63
+ [tool.coverage.paths]
64
+ exobrain_database_model = ["src/exobrain/database", "*/exobrain-database/src/exobrain/database"]
65
+ tests = ["tests", "*/exobrain-database/tests"]
66
+
67
+ [tool.coverage.report]
68
+ exclude_lines = [
69
+ "no cov",
70
+ "if __name__ == .__main__.:",
71
+ "if TYPE_CHECKING:",
72
+ ]
73
+
74
+ # -----------------------------------------------
75
+ # Configuration for "mypy" static type checker
76
+ # -----------------------------------------------
77
+
78
+ [tool.mypy]
79
+ python_version = "3.13"
80
+ namespace_packages = true
81
+ explicit_package_bases = true
82
+ mypy_path = "src"
83
+ ignore_missing_imports = true
84
+ strict = true
85
+ exclude = [
86
+ "src/exobrain/database/migrations/versions",
87
+ ]
88
+
89
+ # -----------------------------------------------
90
+ # Configuration for "ruff" linter
91
+ # -----------------------------------------------
92
+
93
+ [tool.ruff]
94
+ line-length = 120
95
+ indent-width = 4
96
+ target-version = "py312"
97
+ exclude = [
98
+ "src/exobrain/database/migrations/versions",
99
+ ]
100
+
101
+ # -----------------------------------------------
102
+ # Configuration for "ty" type checker
103
+ # -----------------------------------------------
104
+
105
+ [tool.ty.rules]
106
+ all = "error"
107
+ missing-override-decorator = "ignore"
108
+
109
+ [tool.ty.src]
110
+ exclude = [
111
+ "src/exobrain/database/migrations/versions",
112
+ ]
113
+
114
+ [tool.ty.environment]
115
+ python-version = "3.12"
@@ -0,0 +1 @@
1
+ Generic single-database configuration.
@@ -0,0 +1,9 @@
1
+ """Database migration utilities for multi-tenant organization schemas."""
2
+
3
+ from exobrain.database.migrations.migration_manager import (
4
+ configure,
5
+ downgrade,
6
+ upgrade,
7
+ )
8
+
9
+ __all__ = ["configure", "upgrade", "downgrade"]
@@ -0,0 +1,104 @@
1
+ # A generic, single database configuration.
2
+
3
+ [alembic]
4
+ script_location = %(here)s
5
+ version_locations = %(here)s/versions
6
+ file_template = %%(year)d_%%(month).2d_%%(day).2d_%%(hour).2d%%(minute).2d-%%(rev)s_%%(slug)s
7
+
8
+ timezone = UTC
9
+
10
+
11
+ # sys.path path, will be prepended to sys.path if present.
12
+ # defaults to the current working directory.
13
+ prepend_sys_path = .
14
+
15
+ # timezone to use when rendering the date within the migration file
16
+ # as well as the filename.
17
+ # If specified, requires the python-dateutil library that can be
18
+ # installed by adding `alembic[tz]` to the pip requirements
19
+ # string value is passed to dateutil.tz.gettz()
20
+ # leave blank for localtime
21
+ # timezone =
22
+
23
+ # max length of characters to apply to the
24
+ # "slug" field
25
+ # truncate_slug_length = 40
26
+
27
+ # set to 'true' to run the environment during
28
+ # the 'revision' command, regardless of autogenerate
29
+ # revision_environment = false
30
+
31
+ # set to 'true' to allow .pyc and .pyo files without
32
+ # a source .py file to be detected as revisions in the
33
+ # versions/ directory
34
+ # sourceless = false
35
+
36
+ # version location specification; This defaults
37
+ # to alembic/versions. When using multiple version
38
+ # directories, initial revisions must be specified with --version-path.
39
+ # The path separator used here should be the separator specified by "version_path_separator" below.
40
+
41
+ # version path separator; As mentioned above, this is the character used to split
42
+ # version_locations. The default within new alembic.ini files is "os", which uses os.pathsep.
43
+ # If this key is omitted entirely, it falls back to the legacy behavior of splitting on spaces and/or commas.
44
+ # Valid values for version_path_separator are:
45
+ #
46
+ # version_path_separator = :
47
+ # version_path_separator = ;
48
+ # version_path_separator = space
49
+ version_path_separator = :
50
+
51
+ # set to 'true' to search source files recursively
52
+ # in each "version_locations" directory
53
+ # new in Alembic version 1.10
54
+ # recursive_version_locations = false
55
+
56
+ # the output encoding used when revision files
57
+ # are written from script.py.mako
58
+ # output_encoding = utf-8
59
+
60
+ [post_write_hooks]
61
+ # post_write_hooks defines scripts or Python functions that are run
62
+ # on newly generated revision scripts. See the documentation for further
63
+ # detail and examples
64
+
65
+ # format using "black" - use the console_scripts runner, against the "black" entrypoint
66
+ # hooks = black
67
+ # black.type = console_scripts
68
+ # black.entrypoint = black
69
+ # black.options = -l 79 REVISION_SCRIPT_FILENAME
70
+
71
+ # Logging configuration
72
+ [loggers]
73
+ keys = root,sqlalchemy,alembic
74
+
75
+ [handlers]
76
+ keys = console
77
+
78
+ [formatters]
79
+ keys = generic
80
+
81
+ [logger_root]
82
+ level = WARN
83
+ handlers = console
84
+ qualname =
85
+
86
+ [logger_sqlalchemy]
87
+ level = WARN
88
+ handlers =
89
+ qualname = sqlalchemy.engine
90
+
91
+ [logger_alembic]
92
+ level = INFO
93
+ handlers =
94
+ qualname = alembic
95
+
96
+ [handler_console]
97
+ class = StreamHandler
98
+ args = (sys.stderr,)
99
+ level = NOTSET
100
+ formatter = generic
101
+
102
+ [formatter_generic]
103
+ format = %(levelname)-5.5s [%(name)s] %(message)s
104
+ datefmt = %H:%M:%S