openconstructionerp 0.2.1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (225) hide show
  1. openconstructionerp-0.2.1/.env.example +25 -0
  2. openconstructionerp-0.2.1/.gitignore +115 -0
  3. openconstructionerp-0.2.1/CLAUDE.md +60 -0
  4. openconstructionerp-0.2.1/PKG-INFO +138 -0
  5. openconstructionerp-0.2.1/README.md +45 -0
  6. openconstructionerp-0.2.1/alembic/env.py +71 -0
  7. openconstructionerp-0.2.1/alembic/script.py.mako +26 -0
  8. openconstructionerp-0.2.1/alembic/versions/129188e46db8_init_create_all_tables.py +32 -0
  9. openconstructionerp-0.2.1/alembic.ini +35 -0
  10. openconstructionerp-0.2.1/app/__init__.py +0 -0
  11. openconstructionerp-0.2.1/app/__main__.py +56 -0
  12. openconstructionerp-0.2.1/app/cli.py +236 -0
  13. openconstructionerp-0.2.1/app/cli_static.py +92 -0
  14. openconstructionerp-0.2.1/app/config.py +94 -0
  15. openconstructionerp-0.2.1/app/core/__init__.py +0 -0
  16. openconstructionerp-0.2.1/app/core/cache.py +180 -0
  17. openconstructionerp-0.2.1/app/core/demo_projects.py +2551 -0
  18. openconstructionerp-0.2.1/app/core/events.py +174 -0
  19. openconstructionerp-0.2.1/app/core/hooks.py +167 -0
  20. openconstructionerp-0.2.1/app/core/i18n.py +3221 -0
  21. openconstructionerp-0.2.1/app/core/i18n_router.py +24 -0
  22. openconstructionerp-0.2.1/app/core/marketplace.py +1015 -0
  23. openconstructionerp-0.2.1/app/core/module_loader.py +234 -0
  24. openconstructionerp-0.2.1/app/core/permissions.py +159 -0
  25. openconstructionerp-0.2.1/app/core/plugin_manager.py +229 -0
  26. openconstructionerp-0.2.1/app/core/rate_limiter.py +40 -0
  27. openconstructionerp-0.2.1/app/core/sqlite_migrator.py +86 -0
  28. openconstructionerp-0.2.1/app/core/validation/__init__.py +0 -0
  29. openconstructionerp-0.2.1/app/core/validation/engine.py +391 -0
  30. openconstructionerp-0.2.1/app/core/validation/rules/__init__.py +1853 -0
  31. openconstructionerp-0.2.1/app/core/vector.py +345 -0
  32. openconstructionerp-0.2.1/app/database.py +126 -0
  33. openconstructionerp-0.2.1/app/dependencies.py +193 -0
  34. openconstructionerp-0.2.1/app/main.py +713 -0
  35. openconstructionerp-0.2.1/app/middleware/__init__.py +0 -0
  36. openconstructionerp-0.2.1/app/middleware/fingerprint.py +34 -0
  37. openconstructionerp-0.2.1/app/modules/__init__.py +0 -0
  38. openconstructionerp-0.2.1/app/modules/ai/__init__.py +13 -0
  39. openconstructionerp-0.2.1/app/modules/ai/ai_client.py +506 -0
  40. openconstructionerp-0.2.1/app/modules/ai/manifest.py +15 -0
  41. openconstructionerp-0.2.1/app/modules/ai/models.py +95 -0
  42. openconstructionerp-0.2.1/app/modules/ai/permissions.py +16 -0
  43. openconstructionerp-0.2.1/app/modules/ai/prompts.py +198 -0
  44. openconstructionerp-0.2.1/app/modules/ai/repository.py +78 -0
  45. openconstructionerp-0.2.1/app/modules/ai/router.py +858 -0
  46. openconstructionerp-0.2.1/app/modules/ai/schemas.py +155 -0
  47. openconstructionerp-0.2.1/app/modules/ai/service.py +1033 -0
  48. openconstructionerp-0.2.1/app/modules/assemblies/__init__.py +13 -0
  49. openconstructionerp-0.2.1/app/modules/assemblies/manifest.py +18 -0
  50. openconstructionerp-0.2.1/app/modules/assemblies/models.py +114 -0
  51. openconstructionerp-0.2.1/app/modules/assemblies/permissions.py +16 -0
  52. openconstructionerp-0.2.1/app/modules/assemblies/repository.py +196 -0
  53. openconstructionerp-0.2.1/app/modules/assemblies/router.py +473 -0
  54. openconstructionerp-0.2.1/app/modules/assemblies/schemas.py +173 -0
  55. openconstructionerp-0.2.1/app/modules/assemblies/service.py +677 -0
  56. openconstructionerp-0.2.1/app/modules/backup/__init__.py +0 -0
  57. openconstructionerp-0.2.1/app/modules/backup/manifest.py +12 -0
  58. openconstructionerp-0.2.1/app/modules/backup/router.py +470 -0
  59. openconstructionerp-0.2.1/app/modules/boq/__init__.py +12 -0
  60. openconstructionerp-0.2.1/app/modules/boq/ai_prompts.py +178 -0
  61. openconstructionerp-0.2.1/app/modules/boq/cad_import.py +745 -0
  62. openconstructionerp-0.2.1/app/modules/boq/epd_materials.py +266 -0
  63. openconstructionerp-0.2.1/app/modules/boq/events.py +156 -0
  64. openconstructionerp-0.2.1/app/modules/boq/manifest.py +15 -0
  65. openconstructionerp-0.2.1/app/modules/boq/models.py +272 -0
  66. openconstructionerp-0.2.1/app/modules/boq/pdf_export.py +1035 -0
  67. openconstructionerp-0.2.1/app/modules/boq/permissions.py +18 -0
  68. openconstructionerp-0.2.1/app/modules/boq/repository.py +342 -0
  69. openconstructionerp-0.2.1/app/modules/boq/router.py +3788 -0
  70. openconstructionerp-0.2.1/app/modules/boq/schemas.py +897 -0
  71. openconstructionerp-0.2.1/app/modules/boq/service.py +3368 -0
  72. openconstructionerp-0.2.1/app/modules/boq/templates.py +1274 -0
  73. openconstructionerp-0.2.1/app/modules/cad/__init__.py +0 -0
  74. openconstructionerp-0.2.1/app/modules/cad/manifest.py +15 -0
  75. openconstructionerp-0.2.1/app/modules/catalog/__init__.py +13 -0
  76. openconstructionerp-0.2.1/app/modules/catalog/manifest.py +15 -0
  77. openconstructionerp-0.2.1/app/modules/catalog/models.py +60 -0
  78. openconstructionerp-0.2.1/app/modules/catalog/permissions.py +17 -0
  79. openconstructionerp-0.2.1/app/modules/catalog/repository.py +199 -0
  80. openconstructionerp-0.2.1/app/modules/catalog/router.py +392 -0
  81. openconstructionerp-0.2.1/app/modules/catalog/schemas.py +111 -0
  82. openconstructionerp-0.2.1/app/modules/catalog/service.py +462 -0
  83. openconstructionerp-0.2.1/app/modules/changeorders/__init__.py +12 -0
  84. openconstructionerp-0.2.1/app/modules/changeorders/manifest.py +15 -0
  85. openconstructionerp-0.2.1/app/modules/changeorders/models.py +93 -0
  86. openconstructionerp-0.2.1/app/modules/changeorders/permissions.py +17 -0
  87. openconstructionerp-0.2.1/app/modules/changeorders/repository.py +145 -0
  88. openconstructionerp-0.2.1/app/modules/changeorders/router.py +320 -0
  89. openconstructionerp-0.2.1/app/modules/changeorders/schemas.py +157 -0
  90. openconstructionerp-0.2.1/app/modules/changeorders/service.py +317 -0
  91. openconstructionerp-0.2.1/app/modules/costmodel/__init__.py +13 -0
  92. openconstructionerp-0.2.1/app/modules/costmodel/manifest.py +18 -0
  93. openconstructionerp-0.2.1/app/modules/costmodel/models.py +156 -0
  94. openconstructionerp-0.2.1/app/modules/costmodel/permissions.py +15 -0
  95. openconstructionerp-0.2.1/app/modules/costmodel/repository.py +322 -0
  96. openconstructionerp-0.2.1/app/modules/costmodel/router.py +449 -0
  97. openconstructionerp-0.2.1/app/modules/costmodel/schemas.py +333 -0
  98. openconstructionerp-0.2.1/app/modules/costmodel/service.py +1061 -0
  99. openconstructionerp-0.2.1/app/modules/costs/__init__.py +12 -0
  100. openconstructionerp-0.2.1/app/modules/costs/manifest.py +15 -0
  101. openconstructionerp-0.2.1/app/modules/costs/models.py +56 -0
  102. openconstructionerp-0.2.1/app/modules/costs/permissions.py +18 -0
  103. openconstructionerp-0.2.1/app/modules/costs/repository.py +169 -0
  104. openconstructionerp-0.2.1/app/modules/costs/router.py +1948 -0
  105. openconstructionerp-0.2.1/app/modules/costs/schemas.py +110 -0
  106. openconstructionerp-0.2.1/app/modules/costs/service.py +235 -0
  107. openconstructionerp-0.2.1/app/modules/documents/__init__.py +12 -0
  108. openconstructionerp-0.2.1/app/modules/documents/manifest.py +15 -0
  109. openconstructionerp-0.2.1/app/modules/documents/models.py +51 -0
  110. openconstructionerp-0.2.1/app/modules/documents/permissions.py +16 -0
  111. openconstructionerp-0.2.1/app/modules/documents/repository.py +103 -0
  112. openconstructionerp-0.2.1/app/modules/documents/router.py +201 -0
  113. openconstructionerp-0.2.1/app/modules/documents/schemas.py +59 -0
  114. openconstructionerp-0.2.1/app/modules/documents/service.py +213 -0
  115. openconstructionerp-0.2.1/app/modules/projects/__init__.py +12 -0
  116. openconstructionerp-0.2.1/app/modules/projects/manifest.py +15 -0
  117. openconstructionerp-0.2.1/app/modules/projects/models.py +52 -0
  118. openconstructionerp-0.2.1/app/modules/projects/permissions.py +16 -0
  119. openconstructionerp-0.2.1/app/modules/projects/repository.py +81 -0
  120. openconstructionerp-0.2.1/app/modules/projects/router.py +235 -0
  121. openconstructionerp-0.2.1/app/modules/projects/schemas.py +79 -0
  122. openconstructionerp-0.2.1/app/modules/projects/service.py +160 -0
  123. openconstructionerp-0.2.1/app/modules/reporting/__init__.py +0 -0
  124. openconstructionerp-0.2.1/app/modules/reporting/manifest.py +15 -0
  125. openconstructionerp-0.2.1/app/modules/risk/__init__.py +12 -0
  126. openconstructionerp-0.2.1/app/modules/risk/manifest.py +15 -0
  127. openconstructionerp-0.2.1/app/modules/risk/models.py +54 -0
  128. openconstructionerp-0.2.1/app/modules/risk/permissions.py +16 -0
  129. openconstructionerp-0.2.1/app/modules/risk/repository.py +84 -0
  130. openconstructionerp-0.2.1/app/modules/risk/router.py +183 -0
  131. openconstructionerp-0.2.1/app/modules/risk/schemas.py +132 -0
  132. openconstructionerp-0.2.1/app/modules/risk/service.py +234 -0
  133. openconstructionerp-0.2.1/app/modules/schedule/__init__.py +12 -0
  134. openconstructionerp-0.2.1/app/modules/schedule/manifest.py +15 -0
  135. openconstructionerp-0.2.1/app/modules/schedule/models.py +170 -0
  136. openconstructionerp-0.2.1/app/modules/schedule/permissions.py +17 -0
  137. openconstructionerp-0.2.1/app/modules/schedule/repository.py +206 -0
  138. openconstructionerp-0.2.1/app/modules/schedule/router.py +487 -0
  139. openconstructionerp-0.2.1/app/modules/schedule/schemas.py +354 -0
  140. openconstructionerp-0.2.1/app/modules/schedule/service.py +1677 -0
  141. openconstructionerp-0.2.1/app/modules/takeoff/__init__.py +8 -0
  142. openconstructionerp-0.2.1/app/modules/takeoff/manifest.py +15 -0
  143. openconstructionerp-0.2.1/app/modules/takeoff/models.py +56 -0
  144. openconstructionerp-0.2.1/app/modules/takeoff/permissions.py +16 -0
  145. openconstructionerp-0.2.1/app/modules/takeoff/repository.py +51 -0
  146. openconstructionerp-0.2.1/app/modules/takeoff/router.py +990 -0
  147. openconstructionerp-0.2.1/app/modules/takeoff/schemas.py +86 -0
  148. openconstructionerp-0.2.1/app/modules/takeoff/service.py +211 -0
  149. openconstructionerp-0.2.1/app/modules/tendering/__init__.py +1 -0
  150. openconstructionerp-0.2.1/app/modules/tendering/manifest.py +15 -0
  151. openconstructionerp-0.2.1/app/modules/tendering/models.py +92 -0
  152. openconstructionerp-0.2.1/app/modules/tendering/permissions.py +19 -0
  153. openconstructionerp-0.2.1/app/modules/tendering/repository.py +120 -0
  154. openconstructionerp-0.2.1/app/modules/tendering/router.py +430 -0
  155. openconstructionerp-0.2.1/app/modules/tendering/schemas.py +160 -0
  156. openconstructionerp-0.2.1/app/modules/tendering/service.py +317 -0
  157. openconstructionerp-0.2.1/app/modules/users/__init__.py +11 -0
  158. openconstructionerp-0.2.1/app/modules/users/manifest.py +15 -0
  159. openconstructionerp-0.2.1/app/modules/users/models.py +82 -0
  160. openconstructionerp-0.2.1/app/modules/users/permissions.py +18 -0
  161. openconstructionerp-0.2.1/app/modules/users/repository.py +123 -0
  162. openconstructionerp-0.2.1/app/modules/users/router.py +266 -0
  163. openconstructionerp-0.2.1/app/modules/users/schemas.py +158 -0
  164. openconstructionerp-0.2.1/app/modules/users/service.py +476 -0
  165. openconstructionerp-0.2.1/app/modules/validation/__init__.py +0 -0
  166. openconstructionerp-0.2.1/app/schemas.py +268 -0
  167. openconstructionerp-0.2.1/app/scripts/__init__.py +0 -0
  168. openconstructionerp-0.2.1/app/scripts/create_tables.py +26 -0
  169. openconstructionerp-0.2.1/app/scripts/export_catalog_csv.py +245 -0
  170. openconstructionerp-0.2.1/app/scripts/export_full_catalog.py +288 -0
  171. openconstructionerp-0.2.1/app/scripts/seed_catalog.py +227 -0
  172. openconstructionerp-0.2.1/app/scripts/seed_demo.py +252 -0
  173. openconstructionerp-0.2.1/app/scripts/seed_demo_4d5d.py +273 -0
  174. openconstructionerp-0.2.1/app/scripts/seed_demo_estimates.py +859 -0
  175. openconstructionerp-0.2.1/app/scripts/seed_international.py +231 -0
  176. openconstructionerp-0.2.1/app/scripts/seed_schedule_demo.py +674 -0
  177. openconstructionerp-0.2.1/app/scripts/seed_sections.py +77 -0
  178. openconstructionerp-0.2.1/build_all_catalogs.py +247 -0
  179. openconstructionerp-0.2.1/build_catalog.py +94 -0
  180. openconstructionerp-0.2.1/locales/ar.json +163 -0
  181. openconstructionerp-0.2.1/locales/cs.json +141 -0
  182. openconstructionerp-0.2.1/locales/da.json +141 -0
  183. openconstructionerp-0.2.1/locales/de.json +182 -0
  184. openconstructionerp-0.2.1/locales/en.json +182 -0
  185. openconstructionerp-0.2.1/locales/es.json +141 -0
  186. openconstructionerp-0.2.1/locales/fi.json +141 -0
  187. openconstructionerp-0.2.1/locales/fr.json +141 -0
  188. openconstructionerp-0.2.1/locales/hi.json +141 -0
  189. openconstructionerp-0.2.1/locales/it.json +141 -0
  190. openconstructionerp-0.2.1/locales/ja.json +141 -0
  191. openconstructionerp-0.2.1/locales/ko.json +141 -0
  192. openconstructionerp-0.2.1/locales/nl.json +141 -0
  193. openconstructionerp-0.2.1/locales/no.json +141 -0
  194. openconstructionerp-0.2.1/locales/pl.json +141 -0
  195. openconstructionerp-0.2.1/locales/pt.json +141 -0
  196. openconstructionerp-0.2.1/locales/ru.json +182 -0
  197. openconstructionerp-0.2.1/locales/sv.json +141 -0
  198. openconstructionerp-0.2.1/locales/tr.json +141 -0
  199. openconstructionerp-0.2.1/locales/zh.json +141 -0
  200. openconstructionerp-0.2.1/openestimate-server.spec +54 -0
  201. openconstructionerp-0.2.1/pyproject.toml +192 -0
  202. openconstructionerp-0.2.1/qa_ai_test.py +303 -0
  203. openconstructionerp-0.2.1/qa_api_test.py +1785 -0
  204. openconstructionerp-0.2.1/requirements.txt +238 -0
  205. openconstructionerp-0.2.1/tests/__init__.py +0 -0
  206. openconstructionerp-0.2.1/tests/conftest.py +110 -0
  207. openconstructionerp-0.2.1/tests/integration/__init__.py +0 -0
  208. openconstructionerp-0.2.1/tests/integration/test_api_smoke.py +286 -0
  209. openconstructionerp-0.2.1/tests/integration/test_full_platform.py +1496 -0
  210. openconstructionerp-0.2.1/tests/unit/__init__.py +0 -0
  211. openconstructionerp-0.2.1/tests/unit/test_ai_client.py +171 -0
  212. openconstructionerp-0.2.1/tests/unit/test_ai_prompts.py +108 -0
  213. openconstructionerp-0.2.1/tests/unit/test_boq_schemas.py +300 -0
  214. openconstructionerp-0.2.1/tests/unit/test_boq_templates.py +123 -0
  215. openconstructionerp-0.2.1/tests/unit/test_config.py +166 -0
  216. openconstructionerp-0.2.1/tests/unit/test_cost_schemas.py +163 -0
  217. openconstructionerp-0.2.1/tests/unit/test_database.py +151 -0
  218. openconstructionerp-0.2.1/tests/unit/test_events_hooks.py +198 -0
  219. openconstructionerp-0.2.1/tests/unit/test_i18n.py +203 -0
  220. openconstructionerp-0.2.1/tests/unit/test_permissions.py +376 -0
  221. openconstructionerp-0.2.1/tests/unit/test_project_schemas.py +137 -0
  222. openconstructionerp-0.2.1/tests/unit/test_schemas_core.py +247 -0
  223. openconstructionerp-0.2.1/tests/unit/test_users.py +580 -0
  224. openconstructionerp-0.2.1/tests/unit/test_validation_engine.py +237 -0
  225. openconstructionerp-0.2.1/tmp_api.json +1 -0
@@ -0,0 +1,25 @@
1
+ # Database (default: SQLite, no config needed)
2
+ # DATABASE_URL=sqlite+aiosqlite:///./openestimate.db
3
+ # For PostgreSQL:
4
+ # DATABASE_URL=postgresql+asyncpg://user:password@localhost:5432/openestimate
5
+
6
+ # Auth
7
+ JWT_SECRET=change-me-in-production
8
+
9
+ # Redis (optional)
10
+ # REDIS_URL=redis://localhost:6379/0
11
+
12
+ # S3/MinIO (optional)
13
+ # S3_ENDPOINT=http://localhost:9000
14
+ # S3_ACCESS_KEY=minioadmin
15
+ # S3_SECRET_KEY=minioadmin
16
+
17
+ # AI (optional — add your provider key)
18
+ # OPENAI_API_KEY=sk-...
19
+ # ANTHROPIC_API_KEY=sk-ant-...
20
+
21
+ # Vector search backend (default: lancedb)
22
+ # VECTOR_BACKEND=lancedb
23
+
24
+ # Demo accounts (set to false in production)
25
+ # SEED_DEMO=true
@@ -0,0 +1,115 @@
1
+ # Python
2
+ __pycache__/
3
+ *.py[cod]
4
+ *.egg-info/
5
+ dist/
6
+ build/
7
+ .eggs/
8
+ *.egg
9
+ .venv/
10
+ venv/
11
+
12
+ # Node
13
+ node_modules/
14
+ frontend/dist/
15
+
16
+ # IDE
17
+ .vscode/
18
+ .idea/
19
+ *.swp
20
+ *.swo
21
+
22
+ # OS
23
+ .DS_Store
24
+ Thumbs.db
25
+
26
+ # Environment
27
+ .env
28
+ .env.local
29
+ .env.production
30
+
31
+ # Database
32
+ *.db
33
+ *.db-shm
34
+ *.db-wal
35
+ *.sqlite3
36
+ openestimate.db*
37
+
38
+ # Docker volumes
39
+ pg_data/
40
+ minio_data/
41
+ qdrant_data/
42
+
43
+ # Testing
44
+ htmlcov/
45
+ .coverage
46
+ coverage.xml
47
+ .pytest_cache/
48
+ frontend/test-results/
49
+ frontend/e2e-results/
50
+ *.trace.zip
51
+
52
+ # Build
53
+ *.tar.gz
54
+ *.whl
55
+ frontend/stats.html
56
+
57
+ # Logs
58
+ *.log
59
+ logs/
60
+
61
+ # Generated
62
+ backend/locales/
63
+ i18n-audit/
64
+ translation_keys.txt
65
+
66
+ # Claude Code / MCP
67
+ .claude/
68
+ .mcp.json
69
+ .playwright-mcp/
70
+
71
+ # QA / Dev artifacts
72
+ screenshots/
73
+ !docs/screenshots/
74
+ qa-tests/
75
+ ux-review/
76
+ QA_*.md
77
+ UX_*.md
78
+ TESTING_PLAN.md
79
+ TAKEOFF_TESTING_PLAN.md
80
+ IMPROVEMENTS_TODO.md
81
+ AUDIT_*.md
82
+ REVIEW_PROGRESS.md
83
+ test-screenshots/
84
+
85
+ # Dev screenshots & images
86
+ *.png
87
+ *.jpeg
88
+ *.jpg
89
+ !frontend/public/favicon.png
90
+ !frontend/public/logo.png
91
+ !docs/screenshots/*.png
92
+ !frontend/public/og-image.png
93
+ !frontend/public/*.jpg
94
+ !frontend/public/*.jpeg
95
+
96
+ # QA test scripts (contain demo credentials)
97
+ backend/qa_*.py
98
+ backend/tmp_*.json
99
+
100
+ # LanceDB local data
101
+ lancedb_data/
102
+ *.lance
103
+
104
+ # Cached data
105
+ *.parquet
106
+ .openestimator/
107
+
108
+ # Desktop build
109
+ desktop/dist/
110
+ desktop/build/
111
+ desktop/src-tauri/target/
112
+ desktop/src-tauri/binaries/
113
+
114
+ # Backup files
115
+ *.backup.*
@@ -0,0 +1,60 @@
1
+ # CLAUDE.md — Backend (FastAPI)
2
+
3
+ Parent: [../CLAUDE.md](../CLAUDE.md)
4
+
5
+ ## Контекст
6
+
7
+ FastAPI backend для OpenEstimate. Async-first, module-based architecture.
8
+ Все бизнес-модули в `app/modules/`. Core framework в `app/core/`.
9
+
10
+ ## Команды
11
+
12
+ ```bash
13
+ uvicorn app.main:create_app --factory --reload --port 8000
14
+ pytest
15
+ pytest --cov=app --cov-report=term
16
+ ruff check app/ tests/
17
+ ruff format app/ tests/
18
+ alembic upgrade head
19
+ alembic revision --autogenerate -m "description"
20
+ ```
21
+
22
+ ## Архитектурные правила
23
+
24
+ ### Layered Architecture
25
+
26
+ ```
27
+ Router (HTTP) → Service (Business Logic) → Repository (Data Access) → Database
28
+ ↕ ↕
29
+ Events/Hooks SQLAlchemy Models
30
+
31
+ Validation
32
+ ```
33
+
34
+ - **Router**: только HTTP логика. НЕ бизнес-логика.
35
+ - **Service**: вся бизнес-логика. Stateless. Events, hooks, validation.
36
+ - **Repository**: data access. SQLAlchemy queries only.
37
+ - **Models**: SQLAlchemy ORM. Наследуют `app.database.Base`.
38
+ - **Schemas**: Pydantic v2 request/response.
39
+
40
+ ### Database Conventions
41
+
42
+ - Table names: `oe_{module}_{entity}`
43
+ - All tables: `id` (UUID PK), `created_at`, `updated_at`, `created_by`
44
+ - JSONB для metadata
45
+ - Temporal: `valid_from`, `valid_to` для versioned records
46
+
47
+ ### Validation — обязательна при любом импорте данных
48
+
49
+ ```python
50
+ report = await validation_engine.validate(data=parsed, rule_sets=["gaeb", "boq_quality"])
51
+ if report.has_errors:
52
+ return ImportResult(status="validation_failed", report=report)
53
+ ```
54
+
55
+ ### Performance Targets
56
+
57
+ - CRUD: < 200ms (p95)
58
+ - BOQ load 1000 positions: < 500ms
59
+ - Validation 1000 positions: < 2s
60
+ - CWICR search: < 100ms
@@ -0,0 +1,138 @@
1
+ Metadata-Version: 2.4
2
+ Name: openconstructionerp
3
+ Version: 0.2.1
4
+ Summary: The #1 open-source platform for construction cost estimation — BOQ, 4D/5D, AI, CAD/BIM takeoff
5
+ Project-URL: Homepage, https://datadrivenconstruction.io/erp
6
+ Project-URL: Documentation, https://openconstructionerp.com/docs
7
+ Project-URL: Repository, https://github.com/datadrivenconstruction/OpenConstructionERP
8
+ Project-URL: Issues, https://github.com/datadrivenconstruction/OpenConstructionERP/issues
9
+ Project-URL: Changelog, https://github.com/datadrivenconstruction/OpenConstructionERP/blob/main/CHANGELOG.md
10
+ Author-email: Artem Boiko <info@datadrivenconstruction.io>
11
+ Maintainer-email: Data Driven Construction <info@datadrivenconstruction.io>
12
+ License-Expression: AGPL-3.0-or-later
13
+ Keywords: bill-of-quantities,bim,boq,cad,construction,cost-estimation,cwicr,din276,erp,fastapi,gaeb,ifc,masterformat,nrm,open-source,quantity-surveying,react,revit
14
+ Classifier: Development Status :: 4 - Beta
15
+ Classifier: Framework :: FastAPI
16
+ Classifier: Intended Audience :: End Users/Desktop
17
+ Classifier: Intended Audience :: Science/Research
18
+ Classifier: License :: OSI Approved :: GNU Affero General Public License v3 or later (AGPLv3+)
19
+ Classifier: Operating System :: OS Independent
20
+ Classifier: Programming Language :: Python :: 3.12
21
+ Classifier: Programming Language :: Python :: 3.13
22
+ Classifier: Topic :: Office/Business :: Financial
23
+ Classifier: Topic :: Scientific/Engineering
24
+ Requires-Python: >=3.12
25
+ Requires-Dist: aiosqlite>=0.20.0
26
+ Requires-Dist: alembic>=1.14.0
27
+ Requires-Dist: bcrypt>=4.0.0
28
+ Requires-Dist: email-validator>=2.1.0
29
+ Requires-Dist: fastapi>=0.115.0
30
+ Requires-Dist: httpx>=0.28.0
31
+ Requires-Dist: openpyxl>=3.1.0
32
+ Requires-Dist: orjson>=3.10.0
33
+ Requires-Dist: pdfplumber>=0.11.0
34
+ Requires-Dist: pydantic-settings>=2.6.0
35
+ Requires-Dist: pydantic>=2.10.0
36
+ Requires-Dist: python-dateutil>=2.9.0
37
+ Requires-Dist: python-jose[cryptography]>=3.3.0
38
+ Requires-Dist: python-multipart>=0.0.12
39
+ Requires-Dist: reportlab>=4.0.0
40
+ Requires-Dist: sqlalchemy[asyncio]>=2.0.36
41
+ Requires-Dist: structlog>=24.4.0
42
+ Requires-Dist: tenacity>=9.0.0
43
+ Requires-Dist: uvicorn[standard]>=0.32.0
44
+ Provides-Extra: ai
45
+ Requires-Dist: anthropic>=0.40.0; extra == 'ai'
46
+ Requires-Dist: openai>=1.55.0; extra == 'ai'
47
+ Requires-Dist: qdrant-client>=1.12.0; extra == 'ai'
48
+ Requires-Dist: sentence-transformers>=3.3.0; extra == 'ai'
49
+ Provides-Extra: all
50
+ Requires-Dist: anthropic>=0.40.0; extra == 'all'
51
+ Requires-Dist: asyncpg>=0.30.0; extra == 'all'
52
+ Requires-Dist: boto3>=1.35.0; extra == 'all'
53
+ Requires-Dist: celery[redis]>=5.4.0; extra == 'all'
54
+ Requires-Dist: fastembed>=0.4.0; extra == 'all'
55
+ Requires-Dist: lancedb>=0.17.0; extra == 'all'
56
+ Requires-Dist: openai>=1.55.0; extra == 'all'
57
+ Requires-Dist: opencv-python-headless>=4.10.0; extra == 'all'
58
+ Requires-Dist: paddleocr>=2.9.0; extra == 'all'
59
+ Requires-Dist: pillow>=11.0.0; extra == 'all'
60
+ Requires-Dist: psycopg2-binary>=2.9.10; extra == 'all'
61
+ Requires-Dist: pyarrow>=18.0.0; extra == 'all'
62
+ Requires-Dist: pymupdf>=1.25.0; extra == 'all'
63
+ Requires-Dist: qdrant-client>=1.12.0; extra == 'all'
64
+ Requires-Dist: sentence-transformers>=3.3.0; extra == 'all'
65
+ Requires-Dist: ultralytics>=8.3.0; extra == 'all'
66
+ Provides-Extra: cv
67
+ Requires-Dist: opencv-python-headless>=4.10.0; extra == 'cv'
68
+ Requires-Dist: paddleocr>=2.9.0; extra == 'cv'
69
+ Requires-Dist: pillow>=11.0.0; extra == 'cv'
70
+ Requires-Dist: pymupdf>=1.25.0; extra == 'cv'
71
+ Requires-Dist: ultralytics>=8.3.0; extra == 'cv'
72
+ Provides-Extra: dev
73
+ Requires-Dist: factory-boy>=3.3.0; extra == 'dev'
74
+ Requires-Dist: httpx>=0.28.0; extra == 'dev'
75
+ Requires-Dist: mypy>=1.13.0; extra == 'dev'
76
+ Requires-Dist: pre-commit>=4.0.0; extra == 'dev'
77
+ Requires-Dist: pyinstaller>=6.0.0; extra == 'dev'
78
+ Requires-Dist: pytest-asyncio>=0.24.0; extra == 'dev'
79
+ Requires-Dist: pytest-cov>=6.0.0; extra == 'dev'
80
+ Requires-Dist: pytest-xdist>=3.5.0; extra == 'dev'
81
+ Requires-Dist: pytest>=8.3.0; extra == 'dev'
82
+ Requires-Dist: ruff>=0.8.0; extra == 'dev'
83
+ Provides-Extra: server
84
+ Requires-Dist: asyncpg>=0.30.0; extra == 'server'
85
+ Requires-Dist: boto3>=1.35.0; extra == 'server'
86
+ Requires-Dist: celery[redis]>=5.4.0; extra == 'server'
87
+ Requires-Dist: psycopg2-binary>=2.9.10; extra == 'server'
88
+ Provides-Extra: vector
89
+ Requires-Dist: fastembed>=0.4.0; extra == 'vector'
90
+ Requires-Dist: lancedb>=0.17.0; extra == 'vector'
91
+ Requires-Dist: pyarrow>=18.0.0; extra == 'vector'
92
+ Description-Content-Type: text/markdown
93
+
94
+ # OpenConstructionERP
95
+
96
+ **The #1 open-source platform for construction cost estimation**
97
+
98
+ Professional BOQ, 4D scheduling, 5D cost model, AI-powered estimation, CAD/BIM takeoff — all in one platform.
99
+
100
+ ## Quick Start
101
+
102
+ ```bash
103
+ pip install openconstructionerp
104
+ openconstructionerp serve --open
105
+ ```
106
+
107
+ Opens at http://localhost:8080 with SQLite — zero configuration needed.
108
+
109
+ ## Features
110
+
111
+ - **BOQ Editor** — Hierarchical Bill of Quantities with AG Grid, markups, validation, export (PDF/Excel/CSV/GAEB)
112
+ - **55,000+ Cost Items** — CWICR database across 11 regions with resource breakdown
113
+ - **7,000+ Resource Catalog** — Materials, labor, equipment with prices
114
+ - **AI Estimation** — Generate BOQ from text, photo, PDF, Excel, or CAD/BIM (7 LLM providers)
115
+ - **4D Schedule** — Gantt chart with CPM, dependencies, auto-generate from BOQ
116
+ - **5D Cost Model** — Earned Value Management, S-curve, budget tracking
117
+ - **20 Regional Standards** — DIN 276, NRM, MasterFormat, GAEB, and 16 more
118
+ - **21 Languages** — Full i18n with RTL support
119
+ - **42 Validation Rules** — Automatic compliance checking
120
+
121
+ ## CLI Commands
122
+
123
+ ```bash
124
+ openconstructionerp serve [--host HOST] [--port PORT] [--open]
125
+ openconstructionerp init [--data-dir DIR]
126
+ openconstructionerp seed [--demo]
127
+ openconstructionerp version
128
+ ```
129
+
130
+ ## Links
131
+
132
+ - [Documentation](https://openconstructionerp.com/docs)
133
+ - [GitHub](https://github.com/datadrivenconstruction/OpenConstructionERP)
134
+ - [Telegram Community](https://t.me/datadrivenconstruction)
135
+
136
+ ## License
137
+
138
+ AGPL-3.0 — [Data Driven Construction](https://datadrivenconstruction.io)
@@ -0,0 +1,45 @@
1
+ # OpenConstructionERP
2
+
3
+ **The #1 open-source platform for construction cost estimation**
4
+
5
+ Professional BOQ, 4D scheduling, 5D cost model, AI-powered estimation, CAD/BIM takeoff — all in one platform.
6
+
7
+ ## Quick Start
8
+
9
+ ```bash
10
+ pip install openconstructionerp
11
+ openconstructionerp serve --open
12
+ ```
13
+
14
+ Opens at http://localhost:8080 with SQLite — zero configuration needed.
15
+
16
+ ## Features
17
+
18
+ - **BOQ Editor** — Hierarchical Bill of Quantities with AG Grid, markups, validation, export (PDF/Excel/CSV/GAEB)
19
+ - **55,000+ Cost Items** — CWICR database across 11 regions with resource breakdown
20
+ - **7,000+ Resource Catalog** — Materials, labor, equipment with prices
21
+ - **AI Estimation** — Generate BOQ from text, photo, PDF, Excel, or CAD/BIM (7 LLM providers)
22
+ - **4D Schedule** — Gantt chart with CPM, dependencies, auto-generate from BOQ
23
+ - **5D Cost Model** — Earned Value Management, S-curve, budget tracking
24
+ - **20 Regional Standards** — DIN 276, NRM, MasterFormat, GAEB, and 16 more
25
+ - **21 Languages** — Full i18n with RTL support
26
+ - **42 Validation Rules** — Automatic compliance checking
27
+
28
+ ## CLI Commands
29
+
30
+ ```bash
31
+ openconstructionerp serve [--host HOST] [--port PORT] [--open]
32
+ openconstructionerp init [--data-dir DIR]
33
+ openconstructionerp seed [--demo]
34
+ openconstructionerp version
35
+ ```
36
+
37
+ ## Links
38
+
39
+ - [Documentation](https://openconstructionerp.com/docs)
40
+ - [GitHub](https://github.com/datadrivenconstruction/OpenConstructionERP)
41
+ - [Telegram Community](https://t.me/datadrivenconstruction)
42
+
43
+ ## License
44
+
45
+ AGPL-3.0 — [Data Driven Construction](https://datadrivenconstruction.io)
@@ -0,0 +1,71 @@
1
+ """Alembic migration environment.
2
+
3
+ Auto-discovers all module models via Base.metadata.
4
+ """
5
+
6
+ from logging.config import fileConfig
7
+
8
+ from alembic import context
9
+ from sqlalchemy import pool
10
+ from sqlalchemy.engine import Connection
11
+ from sqlalchemy import create_engine
12
+
13
+ from app.config import get_settings
14
+ from app.database import Base
15
+
16
+ # Import all module models so they're registered with Base.metadata.
17
+ # This is done automatically by the module loader at runtime,
18
+ # but we need it here for autogenerate to work.
19
+ from app.modules.users import models as _users # noqa: F401
20
+ from app.modules.projects import models as _projects # noqa: F401
21
+ from app.modules.boq import models as _boq # noqa: F401
22
+ from app.modules.costs import models as _costs # noqa: F401
23
+ from app.modules.assemblies import models as _asm # noqa: F401
24
+ from app.modules.schedule import models as _sched # noqa: F401
25
+ from app.modules.costmodel import models as _cm # noqa: F401
26
+ from app.modules.ai import models as _ai # noqa: F401
27
+ from app.modules.tendering import models as _tender # noqa: F401
28
+ from app.modules.catalog import models as _catalog # noqa: F401
29
+ from app.modules.takeoff import models as _takeoff # noqa: F401
30
+
31
+ config = context.config
32
+ settings = get_settings()
33
+
34
+ # Render UUID columns properly for autogenerate
35
+ def render_item(type_, obj, autogen_context):
36
+ """Custom render for UUID type."""
37
+ if type_ == "type" and hasattr(obj, "__class__") and obj.__class__.__name__ == "GUID":
38
+ return "sa.String(36)"
39
+ return False
40
+
41
+ if config.config_file_name is not None:
42
+ fileConfig(config.config_file_name)
43
+
44
+ target_metadata = Base.metadata
45
+
46
+
47
+ def run_migrations_offline() -> None:
48
+ url = settings.database_sync_url
49
+ context.configure(
50
+ url=url,
51
+ target_metadata=target_metadata,
52
+ literal_binds=True,
53
+ dialect_opts={"paramstyle": "named"},
54
+ )
55
+ with context.begin_transaction():
56
+ context.run_migrations()
57
+
58
+
59
+ def run_migrations_online() -> None:
60
+ connectable = create_engine(settings.database_sync_url, poolclass=pool.NullPool)
61
+
62
+ with connectable.connect() as connection:
63
+ context.configure(connection=connection, target_metadata=target_metadata)
64
+ with context.begin_transaction():
65
+ context.run_migrations()
66
+
67
+
68
+ if context.is_offline_mode():
69
+ run_migrations_offline()
70
+ else:
71
+ run_migrations_online()
@@ -0,0 +1,26 @@
1
+ """${message}
2
+
3
+ Revision ID: ${up_revision}
4
+ Revises: ${down_revision | comma,n}
5
+ Create Date: ${create_date}
6
+
7
+ """
8
+ from typing import Sequence, Union
9
+
10
+ from alembic import op
11
+ import sqlalchemy as sa
12
+ ${imports if imports else ""}
13
+
14
+ # revision identifiers, used by Alembic.
15
+ revision: str = ${repr(up_revision)}
16
+ down_revision: Union[str, None] = ${repr(down_revision)}
17
+ branch_labels: Union[str, Sequence[str], None] = ${repr(branch_labels)}
18
+ depends_on: Union[str, Sequence[str], None] = ${repr(depends_on)}
19
+
20
+
21
+ def upgrade() -> None:
22
+ ${upgrades if upgrades else "pass"}
23
+
24
+
25
+ def downgrade() -> None:
26
+ ${downgrades if downgrades else "pass"}
@@ -0,0 +1,32 @@
1
+ """init: create all tables
2
+
3
+ Revision ID: 129188e46db8
4
+ Revises:
5
+ Create Date: 2026-03-26 14:32:37.263344
6
+
7
+ Note: Tables are auto-created by SQLAlchemy Base.metadata.create_all() at startup.
8
+ This migration exists as a baseline marker for Alembic version tracking.
9
+ On fresh databases, all tables already exist before this migration runs.
10
+ """
11
+ from typing import Sequence, Union
12
+
13
+ from alembic import op
14
+ import sqlalchemy as sa
15
+
16
+
17
+ # revision identifiers, used by Alembic.
18
+ revision: str = '129188e46db8'
19
+ down_revision: Union[str, None] = None
20
+ branch_labels: Union[str, Sequence[str], None] = None
21
+ depends_on: Union[str, Sequence[str], None] = None
22
+
23
+
24
+ def upgrade() -> None:
25
+ # Tables are created by SQLAlchemy at app startup.
26
+ # This migration serves as the Alembic baseline.
27
+ pass
28
+
29
+
30
+ def downgrade() -> None:
31
+ # No-op: tables are managed by SQLAlchemy metadata.
32
+ pass
@@ -0,0 +1,35 @@
1
+ [alembic]
2
+ script_location = alembic
3
+ sqlalchemy.url = sqlite:///./openestimate.db
4
+
5
+ [loggers]
6
+ keys = root,sqlalchemy,alembic
7
+
8
+ [handlers]
9
+ keys = console
10
+
11
+ [formatters]
12
+ keys = generic
13
+
14
+ [logger_root]
15
+ level = WARN
16
+ handlers = console
17
+
18
+ [logger_sqlalchemy]
19
+ level = WARN
20
+ handlers =
21
+ qualname = sqlalchemy.engine
22
+
23
+ [logger_alembic]
24
+ level = INFO
25
+ handlers =
26
+ qualname = alembic
27
+
28
+ [handler_console]
29
+ class = StreamHandler
30
+ args = (sys.stderr,)
31
+ level = NOTSET
32
+ formatter = generic
33
+
34
+ [formatter_generic]
35
+ format = %(levelname)-5.5s [%(name)s] %(message)s
File without changes
@@ -0,0 +1,56 @@
1
+ """Entry point for PyInstaller / standalone execution.
2
+
3
+ Usage:
4
+ python -m app # Dev mode
5
+ openestimate-server.exe # Production (PyInstaller bundle)
6
+ """
7
+
8
+ import os
9
+ import sys
10
+ import multiprocessing
11
+
12
+
13
+ def main() -> None:
14
+ """Start the OpenConstructionERP backend server."""
15
+ import uvicorn
16
+
17
+ # Parse CLI args: --host X --port Y
18
+ host = "127.0.0.1"
19
+ port = 8741
20
+ args = sys.argv[1:]
21
+ for i, arg in enumerate(args):
22
+ if arg == "--host" and i + 1 < len(args):
23
+ host = args[i + 1]
24
+ elif arg == "--port" and i + 1 < len(args):
25
+ try:
26
+ port = int(args[i + 1])
27
+ except ValueError:
28
+ pass
29
+
30
+ # Also check env vars as fallback
31
+ host = os.environ.get("HOST", host)
32
+ port = int(os.environ.get("PORT", str(port)))
33
+
34
+ # Desktop app mode: serve frontend, production settings
35
+ if getattr(sys, "frozen", False):
36
+ os.environ.setdefault("SERVE_FRONTEND", "1")
37
+ os.environ.setdefault("APP_ENV", "production")
38
+ os.environ.setdefault("APP_DEBUG", "false")
39
+
40
+ print(f"Starting OpenConstructionERP on http://{host}:{port}")
41
+
42
+ # Use direct app import for PyInstaller compatibility
43
+ from app.main import create_app
44
+ app = create_app()
45
+
46
+ uvicorn.run(
47
+ app,
48
+ host=host,
49
+ port=port,
50
+ log_level="info",
51
+ )
52
+
53
+
54
+ if __name__ == "__main__":
55
+ multiprocessing.freeze_support()
56
+ main()