celerp 1.2.8__tar.gz → 1.3.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 (558) hide show
  1. {celerp-1.2.8 → celerp-1.3.1}/CONTRIBUTING.md +39 -1
  2. {celerp-1.2.8 → celerp-1.3.1}/NOTICE +10 -0
  3. {celerp-1.2.8 → celerp-1.3.1}/PKG-INFO +11 -2
  4. {celerp-1.2.8 → celerp-1.3.1}/README.md +9 -1
  5. {celerp-1.2.8 → celerp-1.3.1}/celerp/ai/tools.py +5 -4
  6. {celerp-1.2.8 → celerp-1.3.1}/celerp/cli.py +332 -61
  7. {celerp-1.2.8 → celerp-1.3.1}/celerp/config.py +7 -1
  8. celerp-1.3.1/celerp/embedded_pg.py +302 -0
  9. {celerp-1.2.8 → celerp-1.3.1}/celerp/gateway/client.py +29 -1
  10. {celerp-1.2.8 → celerp-1.3.1}/celerp/main.py +7 -0
  11. {celerp-1.2.8 → celerp-1.3.1}/celerp/models/notification.py +1 -1
  12. {celerp-1.2.8 → celerp-1.3.1}/celerp/services/field_schema.py +4 -0
  13. {celerp-1.2.8 → celerp-1.3.1}/celerp/services/fulfill.py +2 -2
  14. {celerp-1.2.8 → celerp-1.3.1}/celerp/services/pick.py +51 -30
  15. celerp-1.3.1/celerp/services/reorder.py +279 -0
  16. {celerp-1.2.8 → celerp-1.3.1}/celerp.egg-info/PKG-INFO +11 -2
  17. {celerp-1.2.8 → celerp-1.3.1}/celerp.egg-info/SOURCES.txt +4 -0
  18. {celerp-1.2.8 → celerp-1.3.1}/celerp.egg-info/requires.txt +3 -0
  19. {celerp-1.2.8 → celerp-1.3.1}/celerp.egg-info/scm_file_list.json +15 -0
  20. celerp-1.3.1/celerp.egg-info/scm_version.json +8 -0
  21. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-dashboard/celerp_dashboard/routes.py +2 -1
  22. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-docs/__init__.py +1 -0
  23. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-docs/celerp_docs/routes.py +123 -10
  24. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-docs/tests/test_audits.py +46 -0
  25. celerp-1.3.1/default_modules/celerp-docs/tests/test_receive_sku_batch.py +73 -0
  26. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-inventory/celerp_inventory/projections.py +87 -15
  27. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-inventory/celerp_inventory/routes.py +153 -93
  28. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-inventory/celerp_inventory/routes_scanning.py +45 -8
  29. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-labels/celerp_labels/ui_routes.py +36 -18
  30. {celerp-1.2.8 → celerp-1.3.1}/pyproject.toml +10 -1
  31. {celerp-1.2.8 → celerp-1.3.1}/ui/api_client.py +11 -2
  32. {celerp-1.2.8 → celerp-1.3.1}/ui/app.py +2 -1
  33. celerp-1.3.1/ui/components/attrs.py +28 -0
  34. {celerp-1.2.8 → celerp-1.3.1}/ui/components/files.py +4 -3
  35. {celerp-1.2.8 → celerp-1.3.1}/ui/components/shell.py +5 -3
  36. {celerp-1.2.8 → celerp-1.3.1}/ui/components/table.py +37 -5
  37. {celerp-1.2.8 → celerp-1.3.1}/ui/locales/en.json +4 -0
  38. {celerp-1.2.8 → celerp-1.3.1}/ui/routes/auth.py +23 -45
  39. {celerp-1.2.8 → celerp-1.3.1}/ui/routes/contacts.py +6 -4
  40. {celerp-1.2.8 → celerp-1.3.1}/ui/routes/csv_import.py +1 -1
  41. {celerp-1.2.8 → celerp-1.3.1}/ui/routes/dashboard.py +10 -10
  42. {celerp-1.2.8 → celerp-1.3.1}/ui/routes/documents.py +243 -27
  43. {celerp-1.2.8 → celerp-1.3.1}/ui/routes/inventory.py +119 -59
  44. {celerp-1.2.8 → celerp-1.3.1}/ui/routes/reconciliation.py +2 -1
  45. {celerp-1.2.8 → celerp-1.3.1}/ui/routes/settings.py +2 -1
  46. {celerp-1.2.8 → celerp-1.3.1}/ui/routes/settings_connectors.py +18 -1
  47. {celerp-1.2.8 → celerp-1.3.1}/ui/routes/settings_inventory.py +82 -1
  48. celerp-1.2.8/celerp.egg-info/scm_version.json +0 -8
  49. {celerp-1.2.8 → celerp-1.3.1}/CLA.md +0 -0
  50. {celerp-1.2.8 → celerp-1.3.1}/LICENSE +0 -0
  51. {celerp-1.2.8 → celerp-1.3.1}/LICENSING.md +0 -0
  52. {celerp-1.2.8 → celerp-1.3.1}/MANIFEST.in +0 -0
  53. {celerp-1.2.8 → celerp-1.3.1}/alembic.ini +0 -0
  54. {celerp-1.2.8 → celerp-1.3.1}/celerp/__init__.py +0 -0
  55. {celerp-1.2.8 → celerp-1.3.1}/celerp/__main__.py +0 -0
  56. {celerp-1.2.8 → celerp-1.3.1}/celerp/ai/__init__.py +0 -0
  57. {celerp-1.2.8 → celerp-1.3.1}/celerp/ai/batch.py +0 -0
  58. {celerp-1.2.8 → celerp-1.3.1}/celerp/ai/cleanup.py +0 -0
  59. {celerp-1.2.8 → celerp-1.3.1}/celerp/ai/commands.py +0 -0
  60. {celerp-1.2.8 → celerp-1.3.1}/celerp/ai/conversations.py +0 -0
  61. {celerp-1.2.8 → celerp-1.3.1}/celerp/ai/files.py +0 -0
  62. {celerp-1.2.8 → celerp-1.3.1}/celerp/ai/intent.py +0 -0
  63. {celerp-1.2.8 → celerp-1.3.1}/celerp/ai/llm.py +0 -0
  64. {celerp-1.2.8 → celerp-1.3.1}/celerp/ai/memory.py +0 -0
  65. {celerp-1.2.8 → celerp-1.3.1}/celerp/ai/models.py +0 -0
  66. {celerp-1.2.8 → celerp-1.3.1}/celerp/ai/page_count.py +0 -0
  67. {celerp-1.2.8 → celerp-1.3.1}/celerp/ai/quota.py +0 -0
  68. {celerp-1.2.8 → celerp-1.3.1}/celerp/ai/service.py +0 -0
  69. {celerp-1.2.8 → celerp-1.3.1}/celerp/alembic.ini +0 -0
  70. {celerp-1.2.8 → celerp-1.3.1}/celerp/alembic_config.py +0 -0
  71. {celerp-1.2.8 → celerp-1.3.1}/celerp/compute/__init__.py +0 -0
  72. {celerp-1.2.8 → celerp-1.3.1}/celerp/compute/aggregations.py +0 -0
  73. {celerp-1.2.8 → celerp-1.3.1}/celerp/compute/valuation.py +0 -0
  74. {celerp-1.2.8 → celerp-1.3.1}/celerp/connectors/__init__.py +0 -0
  75. {celerp-1.2.8 → celerp-1.3.1}/celerp/connectors/base.py +0 -0
  76. {celerp-1.2.8 → celerp-1.3.1}/celerp/connectors/daily_scheduler.py +0 -0
  77. {celerp-1.2.8 → celerp-1.3.1}/celerp/connectors/http.py +0 -0
  78. {celerp-1.2.8 → celerp-1.3.1}/celerp/connectors/images.py +0 -0
  79. {celerp-1.2.8 → celerp-1.3.1}/celerp/connectors/quickbooks.py +0 -0
  80. {celerp-1.2.8 → celerp-1.3.1}/celerp/connectors/registry.py +0 -0
  81. {celerp-1.2.8 → celerp-1.3.1}/celerp/connectors/relay_token.py +0 -0
  82. {celerp-1.2.8 → celerp-1.3.1}/celerp/connectors/shopify.py +0 -0
  83. {celerp-1.2.8 → celerp-1.3.1}/celerp/connectors/sync_runner.py +0 -0
  84. {celerp-1.2.8 → celerp-1.3.1}/celerp/connectors/upsert.py +0 -0
  85. {celerp-1.2.8 → celerp-1.3.1}/celerp/connectors/util.py +0 -0
  86. {celerp-1.2.8 → celerp-1.3.1}/celerp/connectors/webhooks.py +0 -0
  87. {celerp-1.2.8 → celerp-1.3.1}/celerp/connectors/woocommerce.py +0 -0
  88. {celerp-1.2.8 → celerp-1.3.1}/celerp/connectors/xero.py +0 -0
  89. {celerp-1.2.8 → celerp-1.3.1}/celerp/constants.py +0 -0
  90. {celerp-1.2.8 → celerp-1.3.1}/celerp/db.py +0 -0
  91. {celerp-1.2.8 → celerp-1.3.1}/celerp/events/__init__.py +0 -0
  92. {celerp-1.2.8 → celerp-1.3.1}/celerp/events/engine.py +0 -0
  93. {celerp-1.2.8 → celerp-1.3.1}/celerp/events/schemas.py +0 -0
  94. {celerp-1.2.8 → celerp-1.3.1}/celerp/events/types.py +0 -0
  95. {celerp-1.2.8 → celerp-1.3.1}/celerp/gateway/__init__.py +0 -0
  96. {celerp-1.2.8 → celerp-1.3.1}/celerp/gateway/state.py +0 -0
  97. {celerp-1.2.8 → celerp-1.3.1}/celerp/importers/__init__.py +0 -0
  98. {celerp-1.2.8 → celerp-1.3.1}/celerp/importers/importer.py +0 -0
  99. {celerp-1.2.8 → celerp-1.3.1}/celerp/importers/schema.py +0 -0
  100. {celerp-1.2.8 → celerp-1.3.1}/celerp/middleware.py +0 -0
  101. {celerp-1.2.8 → celerp-1.3.1}/celerp/migrations/README.md +0 -0
  102. {celerp-1.2.8 → celerp-1.3.1}/celerp/migrations/_auto_stamp.py +0 -0
  103. {celerp-1.2.8 → celerp-1.3.1}/celerp/migrations/_data_reconcile.py +0 -0
  104. {celerp-1.2.8 → celerp-1.3.1}/celerp/migrations/_json_compat.py +0 -0
  105. {celerp-1.2.8 → celerp-1.3.1}/celerp/migrations/env.py +0 -0
  106. {celerp-1.2.8 → celerp-1.3.1}/celerp/migrations/script.py.mako +0 -0
  107. {celerp-1.2.8 → celerp-1.3.1}/celerp/migrations/versions/a0b1c2d3e4f5_seed_landed_cost_clearing_accounts.py +0 -0
  108. {celerp-1.2.8 → celerp-1.3.1}/celerp/migrations/versions/a1b2c3d4e5f6_add_doc_share_tokens.py +0 -0
  109. {celerp-1.2.8 → celerp-1.3.1}/celerp/migrations/versions/b1c2d3e4f5a6_add_supporter_badges.py +0 -0
  110. {celerp-1.2.8 → celerp-1.3.1}/celerp/migrations/versions/b2c3d4e5f6a7_add_import_batches.py +0 -0
  111. {celerp-1.2.8 → celerp-1.3.1}/celerp/migrations/versions/c1d2e3f4a5b6_add_marketplace.py +0 -0
  112. {celerp-1.2.8 → celerp-1.3.1}/celerp/migrations/versions/c2d3e4f5a6b7_add_is_sync_to_shopify.py +0 -0
  113. {celerp-1.2.8 → celerp-1.3.1}/celerp/migrations/versions/d2e3f4a5b6c7_add_password_reset_token.py +0 -0
  114. {celerp-1.2.8 → celerp-1.3.1}/celerp/migrations/versions/e3f4a5b6c7d8_add_company_is_active.py +0 -0
  115. {celerp-1.2.8 → celerp-1.3.1}/celerp/migrations/versions/e4f5a6b7c8d9_backfill_connector_idempotency_key.py +0 -0
  116. {celerp-1.2.8 → celerp-1.3.1}/celerp/migrations/versions/f1a2b3c4d5e6_move_accounts_marketplace_to_modules.py +0 -0
  117. {celerp-1.2.8 → celerp-1.3.1}/celerp/migrations/versions/fd5de461e14e_initial_schema.py +0 -0
  118. {celerp-1.2.8 → celerp-1.3.1}/celerp/migrations/versions/g1h2i3j4k5l6_add_consignment_flag.py +0 -0
  119. {celerp-1.2.8 → celerp-1.3.1}/celerp/migrations/versions/h2i3j4k5l6m7_add_bank_accounts_and_reconciliation.py +0 -0
  120. {celerp-1.2.8 → celerp-1.3.1}/celerp/migrations/versions/j4k5l6m7n8o9_labels_db_persistence.py +0 -0
  121. {celerp-1.2.8 → celerp-1.3.1}/celerp/migrations/versions/k5l6m7n8o9p0_add_reconciliation_v2.py +0 -0
  122. {celerp-1.2.8 → celerp-1.3.1}/celerp/migrations/versions/l6m7n8o9p0q1_add_sync_runs_table.py +0 -0
  123. {celerp-1.2.8 → celerp-1.3.1}/celerp/migrations/versions/m7n8o9p0q1r2_add_connector_configs_and_outbound_queue.py +0 -0
  124. {celerp-1.2.8 → celerp-1.3.1}/celerp/migrations/versions/n8o9p0q1r2s3_backfill_payment_date.py +0 -0
  125. {celerp-1.2.8 → celerp-1.3.1}/celerp/migrations/versions/o9p0q1r2s3t4_backfill_item_price_fields.py +0 -0
  126. {celerp-1.2.8 → celerp-1.3.1}/celerp/migrations/versions/p1q2r3s4t5u6_add_session_registry_and_user_auth_state.py +0 -0
  127. {celerp-1.2.8 → celerp-1.3.1}/celerp/migrations/versions/q2r3s4t5u6v7_add_system_runtime_state.py +0 -0
  128. {celerp-1.2.8 → celerp-1.3.1}/celerp/migrations/versions/r3s4t5u6v7w8_add_projections_company_entity_type_index.py +0 -0
  129. {celerp-1.2.8 → celerp-1.3.1}/celerp/migrations/versions/s4t5u6v7w8x9_drop_user_company_id_role.py +0 -0
  130. {celerp-1.2.8 → celerp-1.3.1}/celerp/migrations/versions/t5u6v7w8x9y0_seed_inventory_sub_accounts.py +0 -0
  131. {celerp-1.2.8 → celerp-1.3.1}/celerp/migrations/versions/u6v7w8x9y0z1_backfill_item_prices_from_attributes.py +0 -0
  132. {celerp-1.2.8 → celerp-1.3.1}/celerp/migrations/versions/v7w8x9y0z1a2_backfill_purchase_unit_defaults.py +0 -0
  133. {celerp-1.2.8 → celerp-1.3.1}/celerp/migrations/versions/w8x9y0z1a2b3_backfill_category_unit_defaults.py +0 -0
  134. {celerp-1.2.8 → celerp-1.3.1}/celerp/migrations/versions/x7y8z9a0b1c2_add_projection_created_at.py +0 -0
  135. {celerp-1.2.8 → celerp-1.3.1}/celerp/migrations/versions/y8z9a0b1c2d3_per_company_ledger_idempotency.py +0 -0
  136. {celerp-1.2.8 → celerp-1.3.1}/celerp/migrations/versions/z9a0b1c2d3e4_work_centers.py +0 -0
  137. {celerp-1.2.8 → celerp-1.3.1}/celerp/models/__init__.py +0 -0
  138. {celerp-1.2.8 → celerp-1.3.1}/celerp/models/accounting.py +0 -0
  139. {celerp-1.2.8 → celerp-1.3.1}/celerp/models/ai.py +0 -0
  140. {celerp-1.2.8 → celerp-1.3.1}/celerp/models/auth.py +0 -0
  141. {celerp-1.2.8 → celerp-1.3.1}/celerp/models/base.py +0 -0
  142. {celerp-1.2.8 → celerp-1.3.1}/celerp/models/company.py +0 -0
  143. {celerp-1.2.8 → celerp-1.3.1}/celerp/models/connector_config.py +0 -0
  144. {celerp-1.2.8 → celerp-1.3.1}/celerp/models/import_batch.py +0 -0
  145. {celerp-1.2.8 → celerp-1.3.1}/celerp/models/ledger.py +0 -0
  146. {celerp-1.2.8 → celerp-1.3.1}/celerp/models/marketplace.py +0 -0
  147. {celerp-1.2.8 → celerp-1.3.1}/celerp/models/projections.py +0 -0
  148. {celerp-1.2.8 → celerp-1.3.1}/celerp/models/share.py +0 -0
  149. {celerp-1.2.8 → celerp-1.3.1}/celerp/models/supporter.py +0 -0
  150. {celerp-1.2.8 → celerp-1.3.1}/celerp/models/sync_run.py +0 -0
  151. {celerp-1.2.8 → celerp-1.3.1}/celerp/modules/__init__.py +0 -0
  152. {celerp-1.2.8 → celerp-1.3.1}/celerp/modules/api.py +0 -0
  153. {celerp-1.2.8 → celerp-1.3.1}/celerp/modules/audit.py +0 -0
  154. {celerp-1.2.8 → celerp-1.3.1}/celerp/modules/license.py +0 -0
  155. {celerp-1.2.8 → celerp-1.3.1}/celerp/modules/loader.py +0 -0
  156. {celerp-1.2.8 → celerp-1.3.1}/celerp/modules/references.py +0 -0
  157. {celerp-1.2.8 → celerp-1.3.1}/celerp/modules/registry.py +0 -0
  158. {celerp-1.2.8 → celerp-1.3.1}/celerp/modules/slots.py +0 -0
  159. {celerp-1.2.8 → celerp-1.3.1}/celerp/notifications/__init__.py +0 -0
  160. {celerp-1.2.8 → celerp-1.3.1}/celerp/notifications/service.py +0 -0
  161. {celerp-1.2.8 → celerp-1.3.1}/celerp/notifications/sse.py +0 -0
  162. {celerp-1.2.8 → celerp-1.3.1}/celerp/output/__init__.py +0 -0
  163. {celerp-1.2.8 → celerp-1.3.1}/celerp/output/pdf.py +0 -0
  164. {celerp-1.2.8 → celerp-1.3.1}/celerp/output/share_render.py +0 -0
  165. {celerp-1.2.8 → celerp-1.3.1}/celerp/projections/__init__.py +0 -0
  166. {celerp-1.2.8 → celerp-1.3.1}/celerp/projections/engine.py +0 -0
  167. {celerp-1.2.8 → celerp-1.3.1}/celerp/projections/handlers/__init__.py +0 -0
  168. {celerp-1.2.8 → celerp-1.3.1}/celerp/projections/handlers/marketplace.py +0 -0
  169. {celerp-1.2.8 → celerp-1.3.1}/celerp/projections/handlers/scanning.py +0 -0
  170. {celerp-1.2.8 → celerp-1.3.1}/celerp/projections/handlers/shopify.py +0 -0
  171. {celerp-1.2.8 → celerp-1.3.1}/celerp/projections/handlers/system.py +0 -0
  172. {celerp-1.2.8 → celerp-1.3.1}/celerp/routers/__init__.py +0 -0
  173. {celerp-1.2.8 → celerp-1.3.1}/celerp/routers/auth.py +0 -0
  174. {celerp-1.2.8 → celerp-1.3.1}/celerp/routers/companies.py +0 -0
  175. {celerp-1.2.8 → celerp-1.3.1}/celerp/routers/debug.py +0 -0
  176. {celerp-1.2.8 → celerp-1.3.1}/celerp/routers/doctor.py +0 -0
  177. {celerp-1.2.8 → celerp-1.3.1}/celerp/routers/events.py +0 -0
  178. {celerp-1.2.8 → celerp-1.3.1}/celerp/routers/health.py +0 -0
  179. {celerp-1.2.8 → celerp-1.3.1}/celerp/routers/ledger.py +0 -0
  180. {celerp-1.2.8 → celerp-1.3.1}/celerp/routers/notifications.py +0 -0
  181. {celerp-1.2.8 → celerp-1.3.1}/celerp/routers/stars.py +0 -0
  182. {celerp-1.2.8 → celerp-1.3.1}/celerp/routers/system.py +0 -0
  183. {celerp-1.2.8 → celerp-1.3.1}/celerp/schemas/__init__.py +0 -0
  184. {celerp-1.2.8 → celerp-1.3.1}/celerp/services/__init__.py +0 -0
  185. {celerp-1.2.8 → celerp-1.3.1}/celerp/services/activity_redaction.py +0 -0
  186. {celerp-1.2.8 → celerp-1.3.1}/celerp/services/attachments.py +0 -0
  187. {celerp-1.2.8 → celerp-1.3.1}/celerp/services/auth.py +0 -0
  188. {celerp-1.2.8 → celerp-1.3.1}/celerp/services/auto_je.py +0 -0
  189. {celerp-1.2.8 → celerp-1.3.1}/celerp/services/backup.py +0 -0
  190. {celerp-1.2.8 → celerp-1.3.1}/celerp/services/backup_export.py +0 -0
  191. {celerp-1.2.8 → celerp-1.3.1}/celerp/services/backup_import.py +0 -0
  192. {celerp-1.2.8 → celerp-1.3.1}/celerp/services/backup_repo.py +0 -0
  193. {celerp-1.2.8 → celerp-1.3.1}/celerp/services/backup_scheduler.py +0 -0
  194. {celerp-1.2.8 → celerp-1.3.1}/celerp/services/backup_state.py +0 -0
  195. {celerp-1.2.8 → celerp-1.3.1}/celerp/services/demo.py +0 -0
  196. {celerp-1.2.8 → celerp-1.3.1}/celerp/services/dev_release_guard.py +0 -0
  197. {celerp-1.2.8 → celerp-1.3.1}/celerp/services/email.py +0 -0
  198. {celerp-1.2.8 → celerp-1.3.1}/celerp/services/je_keys.py +0 -0
  199. {celerp-1.2.8 → celerp-1.3.1}/celerp/services/landed_cost.py +0 -0
  200. {celerp-1.2.8 → celerp-1.3.1}/celerp/services/line_measures.py +0 -0
  201. {celerp-1.2.8 → celerp-1.3.1}/celerp/services/list_behavior.py +0 -0
  202. {celerp-1.2.8 → celerp-1.3.1}/celerp/services/money.py +0 -0
  203. {celerp-1.2.8 → celerp-1.3.1}/celerp/services/runtime_state.py +0 -0
  204. {celerp-1.2.8 → celerp-1.3.1}/celerp/services/session_tracker.py +0 -0
  205. {celerp-1.2.8 → celerp-1.3.1}/celerp/services/star_cta.py +0 -0
  206. {celerp-1.2.8 → celerp-1.3.1}/celerp/services/supporter_badge.py +0 -0
  207. {celerp-1.2.8 → celerp-1.3.1}/celerp/services/system_health.py +0 -0
  208. {celerp-1.2.8 → celerp-1.3.1}/celerp/services/units.py +0 -0
  209. {celerp-1.2.8 → celerp-1.3.1}/celerp/session_gate.py +0 -0
  210. {celerp-1.2.8 → celerp-1.3.1}/celerp/tax_regimes.py +0 -0
  211. {celerp-1.2.8 → celerp-1.3.1}/celerp.egg-info/dependency_links.txt +0 -0
  212. {celerp-1.2.8 → celerp-1.3.1}/celerp.egg-info/entry_points.txt +0 -0
  213. {celerp-1.2.8 → celerp-1.3.1}/celerp.egg-info/top_level.txt +0 -0
  214. {celerp-1.2.8 → celerp-1.3.1}/conftest.py +0 -0
  215. {celerp-1.2.8 → celerp-1.3.1}/default_modules/__init__.py +0 -0
  216. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-accounting/LICENSE +0 -0
  217. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-accounting/__init__.py +0 -0
  218. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-accounting/celerp_accounting/__init__.py +0 -0
  219. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-accounting/celerp_accounting/api_setup.py +0 -0
  220. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-accounting/celerp_accounting/csv_parser.py +0 -0
  221. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-accounting/celerp_accounting/matcher.py +0 -0
  222. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-accounting/celerp_accounting/models.py +0 -0
  223. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-accounting/celerp_accounting/projections.py +0 -0
  224. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-accounting/celerp_accounting/routes.py +0 -0
  225. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-accounting/celerp_accounting/ui_routes.py +0 -0
  226. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-accounting/tests/test_accounting_banking.py +0 -0
  227. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-accounting/tests/test_accounting_banking_routers.py +0 -0
  228. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-accounting/tests/test_accounting_gaps.py +0 -0
  229. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-accounting/tests/test_accounting_import_idempotency.py +0 -0
  230. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-accounting/tests/test_reconciliation_v2.py +0 -0
  231. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-admin/__init__.py +0 -0
  232. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-admin/celerp_admin/__init__.py +0 -0
  233. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-admin/celerp_admin/routes.py +0 -0
  234. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-admin/celerp_admin/setup.py +0 -0
  235. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-ai/__init__.py +0 -0
  236. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-ai/celerp_ai/__init__.py +0 -0
  237. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-ai/celerp_ai/routes.py +0 -0
  238. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-ai/celerp_ai/setup.py +0 -0
  239. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-ai/celerp_ai/ui_routes.py +0 -0
  240. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-ai/tests/conftest.py +0 -0
  241. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-ai/tests/test_batch.py +0 -0
  242. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-ai/tests/test_cleanup.py +0 -0
  243. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-ai/tests/test_conversations.py +0 -0
  244. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-ai/tests/test_coverage_gaps.py +0 -0
  245. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-ai/tests/test_intent.py +0 -0
  246. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-ai/tests/test_llm.py +0 -0
  247. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-ai/tests/test_memory.py +0 -0
  248. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-ai/tests/test_models.py +0 -0
  249. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-ai/tests/test_page_count.py +0 -0
  250. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-ai/tests/test_quota.py +0 -0
  251. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-ai/tests/test_router.py +0 -0
  252. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-ai/tests/test_routes_coverage.py +0 -0
  253. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-ai/tests/test_service.py +0 -0
  254. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-ai/tests/test_tools.py +0 -0
  255. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-backup/__init__.py +0 -0
  256. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-backup/celerp_backup/__init__.py +0 -0
  257. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-backup/celerp_backup/routes.py +0 -0
  258. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-backup/celerp_backup/setup.py +0 -0
  259. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-connectors/__init__.py +0 -0
  260. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-connectors/celerp_connectors/__init__.py +0 -0
  261. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-connectors/celerp_connectors/models.py +0 -0
  262. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-connectors/celerp_connectors/routes.py +0 -0
  263. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-connectors/tests/__init__.py +0 -0
  264. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-connectors/tests/conftest.py +0 -0
  265. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-connectors/tests/test_compliance.py +0 -0
  266. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-connectors/tests/test_connector_correctness.py +0 -0
  267. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-connectors/tests/test_connectors.py +0 -0
  268. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-connectors/tests/test_images.py +0 -0
  269. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-connectors/tests/test_outbound.py +0 -0
  270. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-connectors/tests/test_quickbooks.py +0 -0
  271. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-connectors/tests/test_rate_limiting.py +0 -0
  272. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-connectors/tests/test_shopify.py +0 -0
  273. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-connectors/tests/test_wiring.py +0 -0
  274. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-connectors/tests/test_woocommerce.py +0 -0
  275. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-connectors/tests/test_woocommerce_webhooks.py +0 -0
  276. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-connectors/tests/test_xero.py +0 -0
  277. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-contacts/LICENSE +0 -0
  278. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-contacts/__init__.py +0 -0
  279. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-contacts/celerp_contacts/__init__.py +0 -0
  280. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-contacts/celerp_contacts/migrations.py +0 -0
  281. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-contacts/celerp_contacts/projections.py +0 -0
  282. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-contacts/celerp_contacts/routes.py +0 -0
  283. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-contacts/celerp_contacts/services.py +0 -0
  284. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-contacts/celerp_contacts/ui_routes.py +0 -0
  285. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-dashboard/LICENSE +0 -0
  286. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-dashboard/__init__.py +0 -0
  287. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-dashboard/celerp_dashboard/__init__.py +0 -0
  288. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-dashboard/celerp_dashboard/setup.py +0 -0
  289. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-docs/LICENSE +0 -0
  290. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-docs/celerp_docs/__init__.py +0 -0
  291. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-docs/celerp_docs/api_setup.py +0 -0
  292. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-docs/celerp_docs/doc_constants.py +0 -0
  293. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-docs/celerp_docs/doc_projections.py +0 -0
  294. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-docs/celerp_docs/doc_service.py +0 -0
  295. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-docs/celerp_docs/models_share.py +0 -0
  296. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-docs/celerp_docs/routes_share.py +0 -0
  297. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-docs/celerp_docs/sequences.py +0 -0
  298. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-docs/celerp_docs/taxes.py +0 -0
  299. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-docs/celerp_docs/ui_routes.py +0 -0
  300. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-docs/tests/conftest.py +0 -0
  301. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-docs/tests/test_freight_je.py +0 -0
  302. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-docs/tests/test_freight_lines.py +0 -0
  303. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-docs/tests/test_fulfill_no_split.py +0 -0
  304. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-docs/tests/test_fulfillment_activity.py +0 -0
  305. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-docs/tests/test_inbound_je_lifecycle.py +0 -0
  306. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-docs/tests/test_inventory_account_reconciliation.py +0 -0
  307. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-docs/tests/test_landed_receive.py +0 -0
  308. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-docs/tests/test_line_delete_persist.py +0 -0
  309. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-docs/tests/test_payment_void_activity.py +0 -0
  310. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-docs/tests/test_send_visibility.py +0 -0
  311. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-docs/tests/test_service_lines.py +0 -0
  312. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-inventory/LICENSE +0 -0
  313. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-inventory/__init__.py +0 -0
  314. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-inventory/celerp_inventory/__init__.py +0 -0
  315. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-inventory/celerp_inventory/models_import_batch.py +0 -0
  316. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-inventory/celerp_inventory/routes_attachments.py +0 -0
  317. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-inventory/celerp_inventory/services.py +0 -0
  318. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-inventory/celerp_inventory/ui_routes.py +0 -0
  319. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-inventory/tests/test_item_recipe_projection.py +0 -0
  320. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-inventory/tests/test_item_workflow_projection.py +0 -0
  321. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-inventory/tests/test_landed_cost_projection.py +0 -0
  322. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-labels/LICENSE +0 -0
  323. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-labels/__init__.py +0 -0
  324. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-labels/celerp_labels/__init__.py +0 -0
  325. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-labels/celerp_labels/migrations/__init__.py +0 -0
  326. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-labels/celerp_labels/migrations/labels_001_create_label_templates.py +0 -0
  327. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-labels/celerp_labels/models.py +0 -0
  328. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-labels/celerp_labels/presets.py +0 -0
  329. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-labels/celerp_labels/routes.py +0 -0
  330. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-labels/celerp_labels/service.py +0 -0
  331. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-labels/requirements.txt +0 -0
  332. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-labels/tests/test_labels.py +0 -0
  333. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-labels/tests/test_labels_module.py +0 -0
  334. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-manufacturing/LICENSE +0 -0
  335. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-manufacturing/__init__.py +0 -0
  336. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-manufacturing/celerp_manufacturing/__init__.py +0 -0
  337. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-manufacturing/celerp_manufacturing/costing.py +0 -0
  338. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-manufacturing/celerp_manufacturing/expansion.py +0 -0
  339. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-manufacturing/celerp_manufacturing/labor.py +0 -0
  340. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-manufacturing/celerp_manufacturing/migrations.py +0 -0
  341. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-manufacturing/celerp_manufacturing/projection_handler.py +0 -0
  342. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-manufacturing/celerp_manufacturing/routes.py +0 -0
  343. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-manufacturing/celerp_manufacturing/ui_routes.py +0 -0
  344. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-manufacturing/requirements.txt +0 -0
  345. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-manufacturing/tests/test_bom_removed.py +0 -0
  346. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-manufacturing/tests/test_build_api.py +0 -0
  347. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-manufacturing/tests/test_item_recipe_api.py +0 -0
  348. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-manufacturing/tests/test_item_workflow_api.py +0 -0
  349. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-manufacturing/tests/test_labor_providers.py +0 -0
  350. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-manufacturing/tests/test_manufacture_from_doc.py +0 -0
  351. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-manufacturing/tests/test_manufacturing.py +0 -0
  352. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-manufacturing/tests/test_manufacturing_import_idempotency.py +0 -0
  353. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-manufacturing/tests/test_manufacturing_module.py +0 -0
  354. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-manufacturing/tests/test_mfg_events.py +0 -0
  355. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-manufacturing/tests/test_phase2_manufacturing_validations.py +0 -0
  356. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-manufacturing/tests/test_production_order.py +0 -0
  357. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-manufacturing/tests/test_recipe_costing.py +0 -0
  358. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-manufacturing/tests/test_recipe_expansion.py +0 -0
  359. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-manufacturing/tests/test_recost_api.py +0 -0
  360. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-manufacturing/tests/test_to_make_allocation.py +0 -0
  361. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-manufacturing/tests/test_where_used.py +0 -0
  362. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-manufacturing/tests/test_work_centers_and_settings.py +0 -0
  363. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-manufacturing/tests/test_workflow_time.py +0 -0
  364. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-reports/LICENSE +0 -0
  365. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-reports/__init__.py +0 -0
  366. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-reports/celerp_reports/__init__.py +0 -0
  367. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-reports/celerp_reports/api_setup.py +0 -0
  368. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-reports/celerp_reports/routes.py +0 -0
  369. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-reports/celerp_reports/ui_routes.py +0 -0
  370. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-reports/tests/test_reports_full.py +0 -0
  371. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-reports/tests/test_reports_unit.py +0 -0
  372. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-subscriptions/LICENSE +0 -0
  373. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-subscriptions/__init__.py +0 -0
  374. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-subscriptions/celerp_subscriptions/__init__.py +0 -0
  375. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-subscriptions/celerp_subscriptions/routes.py +0 -0
  376. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-subscriptions/celerp_subscriptions/ui_routes.py +0 -0
  377. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-subscriptions/tests/test_subscriptions.py +0 -0
  378. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-subscriptions/tests/test_subscriptions_ui.py +0 -0
  379. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-verticals/LICENSE +0 -0
  380. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-verticals/__init__.py +0 -0
  381. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-verticals/celerp_verticals/__init__.py +0 -0
  382. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-verticals/celerp_verticals/categories/accessory_fashion.json +0 -0
  383. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-verticals/celerp_verticals/categories/activewear.json +0 -0
  384. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-verticals/celerp_verticals/categories/art_photography.json +0 -0
  385. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-verticals/celerp_verticals/categories/audio_equipment.json +0 -0
  386. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-verticals/celerp_verticals/categories/bag_handbag.json +0 -0
  387. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-verticals/celerp_verticals/categories/banknote.json +0 -0
  388. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-verticals/celerp_verticals/categories/beauty_tool.json +0 -0
  389. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-verticals/celerp_verticals/categories/bed_bedroom.json +0 -0
  390. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-verticals/celerp_verticals/categories/beer.json +0 -0
  391. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-verticals/celerp_verticals/categories/beverage_nonalc.json +0 -0
  392. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-verticals/celerp_verticals/categories/body_part_auto.json +0 -0
  393. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-verticals/celerp_verticals/categories/book.json +0 -0
  394. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-verticals/celerp_verticals/categories/bottoms.json +0 -0
  395. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-verticals/celerp_verticals/categories/brake_suspension.json +0 -0
  396. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-verticals/celerp_verticals/categories/bullion_coin.json +0 -0
  397. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-verticals/celerp_verticals/categories/camera.json +0 -0
  398. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-verticals/celerp_verticals/categories/colored_stone.json +0 -0
  399. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-verticals/celerp_verticals/categories/comic.json +0 -0
  400. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-verticals/celerp_verticals/categories/commercial_space.json +0 -0
  401. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-verticals/celerp_verticals/categories/component_part.json +0 -0
  402. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-verticals/celerp_verticals/categories/confectionery.json +0 -0
  403. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-verticals/celerp_verticals/categories/consulting_service.json +0 -0
  404. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-verticals/celerp_verticals/categories/decorative_art.json +0 -0
  405. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-verticals/celerp_verticals/categories/diamond.json +0 -0
  406. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-verticals/celerp_verticals/categories/drawing.json +0 -0
  407. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-verticals/celerp_verticals/categories/dress_jumpsuit.json +0 -0
  408. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-verticals/celerp_verticals/categories/electrical_auto.json +0 -0
  409. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-verticals/celerp_verticals/categories/electrical_component.json +0 -0
  410. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-verticals/celerp_verticals/categories/emerald.json +0 -0
  411. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-verticals/celerp_verticals/categories/engine_part.json +0 -0
  412. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-verticals/celerp_verticals/categories/fastener.json +0 -0
  413. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-verticals/celerp_verticals/categories/fertilizer_chemical.json +0 -0
  414. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-verticals/celerp_verticals/categories/film_video.json +0 -0
  415. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-verticals/celerp_verticals/categories/fine_writing_instrument.json +0 -0
  416. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-verticals/celerp_verticals/categories/fluid_lubricant.json +0 -0
  417. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-verticals/celerp_verticals/categories/footwear.json +0 -0
  418. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-verticals/celerp_verticals/categories/fragrance.json +0 -0
  419. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-verticals/celerp_verticals/categories/fresh_food.json +0 -0
  420. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-verticals/celerp_verticals/categories/fresh_produce.json +0 -0
  421. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-verticals/celerp_verticals/categories/frozen_food.json +0 -0
  422. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-verticals/celerp_verticals/categories/gaming_console.json +0 -0
  423. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-verticals/celerp_verticals/categories/gold_bullion.json +0 -0
  424. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-verticals/celerp_verticals/categories/grain_cereal.json +0 -0
  425. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-verticals/celerp_verticals/categories/haircare.json +0 -0
  426. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-verticals/celerp_verticals/categories/hand_tool.json +0 -0
  427. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-verticals/celerp_verticals/categories/ingredient_bulk.json +0 -0
  428. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-verticals/celerp_verticals/categories/interior_part.json +0 -0
  429. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-verticals/celerp_verticals/categories/jewelry.json +0 -0
  430. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-verticals/celerp_verticals/categories/kitchen_dining.json +0 -0
  431. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-verticals/celerp_verticals/categories/laptop.json +0 -0
  432. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-verticals/celerp_verticals/categories/lighting.json +0 -0
  433. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-verticals/celerp_verticals/categories/livestock_feed.json +0 -0
  434. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-verticals/celerp_verticals/categories/makeup.json +0 -0
  435. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-verticals/celerp_verticals/categories/measuring_instrument.json +0 -0
  436. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-verticals/celerp_verticals/categories/medal_token.json +0 -0
  437. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-verticals/celerp_verticals/categories/mineral_specimen.json +0 -0
  438. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-verticals/celerp_verticals/categories/mobile_phone.json +0 -0
  439. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-verticals/celerp_verticals/categories/music_cd.json +0 -0
  440. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-verticals/celerp_verticals/categories/music_vinyl.json +0 -0
  441. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-verticals/celerp_verticals/categories/nail.json +0 -0
  442. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-verticals/celerp_verticals/categories/numismatic_coin.json +0 -0
  443. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-verticals/celerp_verticals/categories/outdoor_furniture.json +0 -0
  444. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-verticals/celerp_verticals/categories/outerwear.json +0 -0
  445. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-verticals/celerp_verticals/categories/packaged_food.json +0 -0
  446. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-verticals/celerp_verticals/categories/painting.json +0 -0
  447. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-verticals/celerp_verticals/categories/parking_bay.json +0 -0
  448. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-verticals/celerp_verticals/categories/pearl.json +0 -0
  449. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-verticals/celerp_verticals/categories/personal_care.json +0 -0
  450. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-verticals/celerp_verticals/categories/pipe_plumbing.json +0 -0
  451. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-verticals/celerp_verticals/categories/platinum_bullion.json +0 -0
  452. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-verticals/celerp_verticals/categories/power_tool.json +0 -0
  453. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-verticals/celerp_verticals/categories/print_edition.json +0 -0
  454. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-verticals/celerp_verticals/categories/residential_unit.json +0 -0
  455. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-verticals/celerp_verticals/categories/rough_gemstone.json +0 -0
  456. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-verticals/celerp_verticals/categories/ruby.json +0 -0
  457. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-verticals/celerp_verticals/categories/saas_plan.json +0 -0
  458. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-verticals/celerp_verticals/categories/safety_ppe.json +0 -0
  459. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-verticals/celerp_verticals/categories/sapphire.json +0 -0
  460. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-verticals/celerp_verticals/categories/sculpture.json +0 -0
  461. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-verticals/celerp_verticals/categories/seating.json +0 -0
  462. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-verticals/celerp_verticals/categories/seeds.json +0 -0
  463. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-verticals/celerp_verticals/categories/silver_bullion.json +0 -0
  464. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-verticals/celerp_verticals/categories/skincare.json +0 -0
  465. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-verticals/celerp_verticals/categories/soft_furnishing.json +0 -0
  466. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-verticals/celerp_verticals/categories/software_addon.json +0 -0
  467. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-verticals/celerp_verticals/categories/software_license.json +0 -0
  468. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-verticals/celerp_verticals/categories/spirit.json +0 -0
  469. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-verticals/celerp_verticals/categories/storage_furniture.json +0 -0
  470. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-verticals/celerp_verticals/categories/swimwear.json +0 -0
  471. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-verticals/celerp_verticals/categories/table_desk.json +0 -0
  472. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-verticals/celerp_verticals/categories/tablet.json +0 -0
  473. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-verticals/celerp_verticals/categories/tire_wheel.json +0 -0
  474. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-verticals/celerp_verticals/categories/tops.json +0 -0
  475. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-verticals/celerp_verticals/categories/trading_card.json +0 -0
  476. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-verticals/celerp_verticals/categories/tv_display.json +0 -0
  477. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-verticals/celerp_verticals/categories/video_game.json +0 -0
  478. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-verticals/celerp_verticals/categories/watch.json +0 -0
  479. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-verticals/celerp_verticals/categories/watch_strap.json +0 -0
  480. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-verticals/celerp_verticals/categories/wine.json +0 -0
  481. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-verticals/celerp_verticals/presets/agricultural.json +0 -0
  482. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-verticals/celerp_verticals/presets/artwork.json +0 -0
  483. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-verticals/celerp_verticals/presets/automotive.json +0 -0
  484. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-verticals/celerp_verticals/presets/blank.json +0 -0
  485. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-verticals/celerp_verticals/presets/books_media.json +0 -0
  486. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-verticals/celerp_verticals/presets/coins_precious_metals.json +0 -0
  487. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-verticals/celerp_verticals/presets/consulting.json +0 -0
  488. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-verticals/celerp_verticals/presets/cosmetics.json +0 -0
  489. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-verticals/celerp_verticals/presets/electronics.json +0 -0
  490. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-verticals/celerp_verticals/presets/fashion.json +0 -0
  491. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-verticals/celerp_verticals/presets/food_beverage.json +0 -0
  492. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-verticals/celerp_verticals/presets/furniture.json +0 -0
  493. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-verticals/celerp_verticals/presets/gemstones.json +0 -0
  494. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-verticals/celerp_verticals/presets/hardware.json +0 -0
  495. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-verticals/celerp_verticals/presets/property_rental.json +0 -0
  496. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-verticals/celerp_verticals/presets/saas.json +0 -0
  497. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-verticals/celerp_verticals/presets/watches.json +0 -0
  498. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-verticals/celerp_verticals/presets/wine_spirits.json +0 -0
  499. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-verticals/celerp_verticals/routes.py +0 -0
  500. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-verticals/celerp_verticals/ui_routes.py +0 -0
  501. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-verticals/tests/test_verticals.py +0 -0
  502. {celerp-1.2.8 → celerp-1.3.1}/default_modules/celerp-verticals/tests/test_verticals_routers.py +0 -0
  503. {celerp-1.2.8 → celerp-1.3.1}/legal/OFFICIAL-COMPONENTS.md +0 -0
  504. {celerp-1.2.8 → celerp-1.3.1}/legal/TRADEMARK.md +0 -0
  505. {celerp-1.2.8 → celerp-1.3.1}/setup.cfg +0 -0
  506. {celerp-1.2.8 → celerp-1.3.1}/test_helpers.py +0 -0
  507. {celerp-1.2.8 → celerp-1.3.1}/ui/__init__.py +0 -0
  508. {celerp-1.2.8 → celerp-1.3.1}/ui/components/__init__.py +0 -0
  509. {celerp-1.2.8 → celerp-1.3.1}/ui/components/activity.py +0 -0
  510. {celerp-1.2.8 → celerp-1.3.1}/ui/components/backup.py +0 -0
  511. {celerp-1.2.8 → celerp-1.3.1}/ui/components/cloud_gate.py +0 -0
  512. {celerp-1.2.8 → celerp-1.3.1}/ui/components/currency.py +0 -0
  513. {celerp-1.2.8 → celerp-1.3.1}/ui/components/notes.py +0 -0
  514. {celerp-1.2.8 → celerp-1.3.1}/ui/components/phone.py +0 -0
  515. {celerp-1.2.8 → celerp-1.3.1}/ui/config.py +0 -0
  516. {celerp-1.2.8 → celerp-1.3.1}/ui/i18n.py +0 -0
  517. {celerp-1.2.8 → celerp-1.3.1}/ui/locales/ar.json +0 -0
  518. {celerp-1.2.8 → celerp-1.3.1}/ui/locales/de.json +0 -0
  519. {celerp-1.2.8 → celerp-1.3.1}/ui/locales/es.json +0 -0
  520. {celerp-1.2.8 → celerp-1.3.1}/ui/locales/fr.json +0 -0
  521. {celerp-1.2.8 → celerp-1.3.1}/ui/locales/id.json +0 -0
  522. {celerp-1.2.8 → celerp-1.3.1}/ui/locales/it.json +0 -0
  523. {celerp-1.2.8 → celerp-1.3.1}/ui/locales/ja.json +0 -0
  524. {celerp-1.2.8 → celerp-1.3.1}/ui/locales/pt.json +0 -0
  525. {celerp-1.2.8 → celerp-1.3.1}/ui/locales/th.json +0 -0
  526. {celerp-1.2.8 → celerp-1.3.1}/ui/locales/vi.json +0 -0
  527. {celerp-1.2.8 → celerp-1.3.1}/ui/routes/__init__.py +0 -0
  528. {celerp-1.2.8 → celerp-1.3.1}/ui/routes/accounting.py +0 -0
  529. {celerp-1.2.8 → celerp-1.3.1}/ui/routes/accounting_import.py +0 -0
  530. {celerp-1.2.8 → celerp-1.3.1}/ui/routes/docs_import.py +0 -0
  531. {celerp-1.2.8 → celerp-1.3.1}/ui/routes/events.py +0 -0
  532. {celerp-1.2.8 → celerp-1.3.1}/ui/routes/lists_import.py +0 -0
  533. {celerp-1.2.8 → celerp-1.3.1}/ui/routes/manufacturing.py +0 -0
  534. {celerp-1.2.8 → celerp-1.3.1}/ui/routes/notifications.py +0 -0
  535. {celerp-1.2.8 → celerp-1.3.1}/ui/routes/reports.py +0 -0
  536. {celerp-1.2.8 → celerp-1.3.1}/ui/routes/search.py +0 -0
  537. {celerp-1.2.8 → celerp-1.3.1}/ui/routes/settings_accounting.py +0 -0
  538. {celerp-1.2.8 → celerp-1.3.1}/ui/routes/settings_cloud.py +0 -0
  539. {celerp-1.2.8 → celerp-1.3.1}/ui/routes/settings_contacts.py +0 -0
  540. {celerp-1.2.8 → celerp-1.3.1}/ui/routes/settings_general.py +0 -0
  541. {celerp-1.2.8 → celerp-1.3.1}/ui/routes/settings_import.py +0 -0
  542. {celerp-1.2.8 → celerp-1.3.1}/ui/routes/settings_manufacturing.py +0 -0
  543. {celerp-1.2.8 → celerp-1.3.1}/ui/routes/settings_purchasing.py +0 -0
  544. {celerp-1.2.8 → celerp-1.3.1}/ui/routes/settings_sales.py +0 -0
  545. {celerp-1.2.8 → celerp-1.3.1}/ui/routes/setup.py +0 -0
  546. {celerp-1.2.8 → celerp-1.3.1}/ui/routes/stars.py +0 -0
  547. {celerp-1.2.8 → celerp-1.3.1}/ui/routes/subscriptions.py +0 -0
  548. {celerp-1.2.8 → celerp-1.3.1}/ui/routes/subscriptions_import.py +0 -0
  549. {celerp-1.2.8 → celerp-1.3.1}/ui/static/app.css +0 -0
  550. {celerp-1.2.8 → celerp-1.3.1}/ui/static/htmx.min.js +0 -0
  551. {celerp-1.2.8 → celerp-1.3.1}/ui/static/icon.png +0 -0
  552. {celerp-1.2.8 → celerp-1.3.1}/ui/static/logo.png +0 -0
  553. {celerp-1.2.8 → celerp-1.3.1}/ui/static/vendor/intl-tel-input/img/flags.webp +0 -0
  554. {celerp-1.2.8 → celerp-1.3.1}/ui/static/vendor/intl-tel-input/img/flags@2x.webp +0 -0
  555. {celerp-1.2.8 → celerp-1.3.1}/ui/static/vendor/intl-tel-input/intlTelInput.min.css +0 -0
  556. {celerp-1.2.8 → celerp-1.3.1}/ui/static/vendor/intl-tel-input/intlTelInput.min.js +0 -0
  557. {celerp-1.2.8 → celerp-1.3.1}/ui/static/vendor/intl-tel-input/intlTelInputWithUtils.min.js +0 -0
  558. {celerp-1.2.8 → celerp-1.3.1}/ui/static/vendor/intl-tel-input/utils.js +0 -0
@@ -58,9 +58,40 @@ celerp upgrade # pip install --upgrade celerp + migrate
58
58
  | `--force` | off | Overwrite existing config |
59
59
  | `--yes` / `-y` | off | Skip the `--force` wipe confirmation (non-interactive) |
60
60
  | `--no-start` | off | Set up, then exit WITHOUT launching servers (service-managed/headless) |
61
+ | `--embedded` | off | Force the bundled PostgreSQL even if a server is reachable (cannot combine with `--db-url`) |
62
+ | `--no-embedded` | off | Never fall back to the bundled PostgreSQL; require an external server |
61
63
 
62
64
  To change ports after init, edit `~/.config/celerp/config.toml` directly.
63
65
 
66
+ ### External vs embedded PostgreSQL
67
+
68
+ `celerp init` picks the database automatically, and **an existing server always wins**:
69
+
70
+ 1. `--db-url` given → that external server (no detection).
71
+ 2. else a PostgreSQL server reachable on `localhost:5432` → use it (as root, init
72
+ provisions the role/database via `sudo -u postgres psql`; otherwise it prints the
73
+ `CREATE USER`/`CREATE DATABASE` to run).
74
+ 3. else the **bundled** PostgreSQL 17 — a self-contained cluster under
75
+ `~/.config/celerp/pgdata`, started from binaries shipped in the
76
+ [`celerp-postgres`](https://github.com/celerp/celerp-postgres) wheel. No `sudo`, no
77
+ system service. Available on Linux x86_64/arm64 (glibc and musl/Alpine) and Windows
78
+ x64, any CPython; on macOS 26+ opt in with `pip install celerp-postgres`. Elsewhere
79
+ init asks you to install PostgreSQL.
80
+
81
+ Override the detection with `--embedded` / `--no-embedded`. The chosen mode is written to
82
+ `config.toml` as `[database] embedded = true|<absent>` and preserved across `--force`
83
+ re-inits, so an external install never silently switches to the bundled cluster.
84
+
85
+ **Moving bundled data to an external server** (e.g. outgrowing single-machine): dump from
86
+ the bundled cluster and restore into the target, using the bundled tools so versions match.
87
+
88
+ ```bash
89
+ BIN=$(celerp status >/dev/null; python -c "from celerp import embedded_pg; print(embedded_pg.bin_dir())")
90
+ "$BIN/pg_dump" "$(python -c "from celerp import embedded_pg,pathlib; from celerp.config import config_path; print(embedded_pg.ensure_cluster(config_path().parent).replace('+asyncpg',''))")" \
91
+ | psql "postgresql://celerp:celerp@newhost:5432/celerp"
92
+ celerp init --force --db-url "postgresql+asyncpg://celerp:celerp@newhost:5432/celerp"
93
+ ```
94
+
64
95
  ### Run as a service (systemd)
65
96
 
66
97
  `celerp init` launches the servers and blocks (good for the one-command desktop
@@ -68,16 +99,23 @@ flow). For a headless box where a process manager owns the lifecycle, set up wit
68
99
  `--no-start` and let systemd run `celerp start`:
69
100
 
70
101
  ```bash
71
- # First boot: provision DB + migrations + config, then exit (do not block).
102
+ # First boot against a system PostgreSQL: provision DB + migrations + config, then
103
+ # exit (do not block). Run as root so init can create the role/database.
72
104
  sudo celerp init --no-start \
73
105
  --db-url "postgresql+asyncpg://celerp:<password>@localhost:5432/celerp" \
74
106
  --api-port 8000 --ui-port 8080
75
107
  ```
76
108
 
109
+ Prefer the bundled database? Drop `--db-url` (and the `sudo` — the bundled cluster needs
110
+ neither) and run `celerp init --no-start` as the service user. The cluster then lives under
111
+ that user's `~/.config/celerp/pgdata`, and the systemd unit needs no `postgresql.service`
112
+ dependency.
113
+
77
114
  ```ini
78
115
  # /etc/systemd/system/celerp.service
79
116
  [Unit]
80
117
  Description=Celerp
118
+ # Drop the postgresql.service dependency line when using the bundled database.
81
119
  After=network.target postgresql.service
82
120
 
83
121
  [Service]
@@ -24,4 +24,14 @@ see legal/TRADEMARK.md.
24
24
  Third-party components included in packaged desktop builds are governed by their
25
25
  own license files; see licenses/.
26
26
 
27
+ Bundled PostgreSQL (pip distribution): on supported platforms the pip package
28
+ declares a dependency on `celerp-postgres` (MIT), whose wheels embed PostgreSQL
29
+ server binaries and client tools so `celerp init` can run a self-contained
30
+ database with no separate install. PostgreSQL is distributed under the PostgreSQL
31
+ License (a permissive OSI-approved license); its full text and copyright notice
32
+ ship inside the celerp-postgres wheels, which repackage binaries built by the
33
+ theseus-rs/postgresql-binaries project. These binaries are used unmodified and
34
+ only when no external PostgreSQL server is configured. See
35
+ https://github.com/celerp/celerp-postgres.
36
+
27
37
  For commercial, OEM, or white-label inquiries: https://celerp.com
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: celerp
3
- Version: 1.2.8
3
+ Version: 1.3.1
4
4
  Summary: Free, self-hosted ERP for small businesses
5
5
  License: Business Source License 1.1
6
6
 
@@ -154,6 +154,7 @@ Requires-Dist: Pillow>=10.0
154
154
  Requires-Dist: pypdf>=4.0
155
155
  Requires-Dist: psycopg2-binary>=2.9
156
156
  Requires-Dist: tzdata>=2024.1
157
+ Requires-Dist: celerp-postgres<18,>=17.10; (sys_platform == "linux" and (platform_machine == "x86_64" or platform_machine == "aarch64")) or (sys_platform == "win32" and platform_machine == "AMD64")
157
158
  Provides-Extra: dev
158
159
  Requires-Dist: pytest>=8.0; extra == "dev"
159
160
  Requires-Dist: pytest-asyncio>=0.23; extra == "dev"
@@ -220,6 +221,10 @@ celerp init # sets up the database and launches Celerp
220
221
  Open **http://localhost:8080**. Done.
221
222
  Your office can securely access the system at your IP address :8080.
222
223
 
224
+ No PostgreSQL to install: `celerp init` uses your existing PostgreSQL server if one is
225
+ running, and otherwise starts a self-contained bundled database — no `sudo`, no system
226
+ service. Point it at a specific server with `celerp init --db-url postgresql+asyncpg://…`.
227
+
223
228
  Running headless or under a process manager? Use `celerp init --no-start` to set up
224
229
  without launching, then have your service run `celerp start` — see
225
230
  [Run as a service (systemd)](CONTRIBUTING.md#run-as-a-service-systemd).
@@ -288,9 +293,13 @@ git clone git@github.com:celerp/celerp.git
288
293
  cd celerp
289
294
  python3 -m venv .venv && source .venv/bin/activate
290
295
  pip install -e ".[dev]"
291
- sudo celerp init # creates DB, runs migrations, starts servers
296
+ celerp init # creates DB, runs migrations, starts servers
292
297
  ```
293
298
 
299
+ `celerp init` boots a bundled PostgreSQL when no server is running, so no `sudo` and no
300
+ system Postgres are required. To develop against your own server instead, pass
301
+ `--db-url postgresql+asyncpg://…`.
302
+
294
303
  Open **http://localhost:8080**. Run tests with `pytest tests/`.
295
304
 
296
305
  See [CONTRIBUTING.md](CONTRIBUTING.md) for environment variables, troubleshooting, and coding guidelines.
@@ -49,6 +49,10 @@ celerp init # sets up the database and launches Celerp
49
49
  Open **http://localhost:8080**. Done.
50
50
  Your office can securely access the system at your IP address :8080.
51
51
 
52
+ No PostgreSQL to install: `celerp init` uses your existing PostgreSQL server if one is
53
+ running, and otherwise starts a self-contained bundled database — no `sudo`, no system
54
+ service. Point it at a specific server with `celerp init --db-url postgresql+asyncpg://…`.
55
+
52
56
  Running headless or under a process manager? Use `celerp init --no-start` to set up
53
57
  without launching, then have your service run `celerp start` — see
54
58
  [Run as a service (systemd)](CONTRIBUTING.md#run-as-a-service-systemd).
@@ -117,9 +121,13 @@ git clone git@github.com:celerp/celerp.git
117
121
  cd celerp
118
122
  python3 -m venv .venv && source .venv/bin/activate
119
123
  pip install -e ".[dev]"
120
- sudo celerp init # creates DB, runs migrations, starts servers
124
+ celerp init # creates DB, runs migrations, starts servers
121
125
  ```
122
126
 
127
+ `celerp init` boots a bundled PostgreSQL when no server is running, so no `sudo` and no
128
+ system Postgres are required. To develop against your own server instead, pass
129
+ `--db-url postgresql+asyncpg://…`.
130
+
123
131
  Open **http://localhost:8080**. Run tests with `pytest tests/`.
124
132
 
125
133
  See [CONTRIBUTING.md](CONTRIBUTING.md) for environment variables, troubleshooting, and coding guidelines.
@@ -22,6 +22,7 @@ from sqlalchemy import select
22
22
  from sqlalchemy.ext.asyncio import AsyncSession
23
23
 
24
24
  from celerp.models.projections import Projection
25
+ from celerp.services.reorder import is_below_reorder
25
26
 
26
27
 
27
28
  @dataclass
@@ -61,7 +62,7 @@ async def _dashboard_kpis(session: AsyncSession, company_id: uuid.UUID, **_) ->
61
62
  return {
62
63
  "total_items": len(items),
63
64
  "inventory_value": round(sum(float(i.state.get("total_cost", 0) or 0) for i in items), 2),
64
- "low_stock_items": sum(1 for i in items if float(i.state.get("quantity", 0) or 0) <= 0),
65
+ "low_stock_items": sum(1 for i in items if is_below_reorder(i.state)),
65
66
  "ar_outstanding": round(
66
67
  sum(
67
68
  float(d.state.get("amount_outstanding", 0) or 0)
@@ -75,12 +76,12 @@ async def _dashboard_kpis(session: AsyncSession, company_id: uuid.UUID, **_) ->
75
76
  async def _low_stock_items(
76
77
  session: AsyncSession, company_id: uuid.UUID, limit: int = 20, **_,
77
78
  ) -> dict:
78
- """List items with zero or negative quantity."""
79
+ """List items at or below their reorder point."""
79
80
  items = await _projections(session, company_id, "item")
80
81
  low = sorted(
81
82
  [
82
83
  {"sku": r.state.get("sku"), "name": r.state.get("name"), "quantity": r.state.get("quantity", 0)}
83
- for r in items if float(r.state.get("quantity", 0) or 0) <= 0
84
+ for r in items if is_below_reorder(r.state)
84
85
  ],
85
86
  key=lambda x: float(x["quantity"] or 0),
86
87
  )
@@ -263,7 +264,7 @@ TOOLS: dict[str, ToolDef] = {
263
264
  t.name: t
264
265
  for t in [
265
266
  ToolDef("dashboard_kpis", "Return high-level KPIs: inventory value, AR outstanding, low stock count, active deals.", [], _dashboard_kpis),
266
- ToolDef("low_stock_items", "List items with zero or negative quantity. Param: limit (default 20).", ["limit"], _low_stock_items),
267
+ ToolDef("low_stock_items", "List items at or below their reorder point (defaults to zero/negative quantity for items without a reorder point set). Param: limit (default 20).", ["limit"], _low_stock_items),
267
268
  ToolDef("outstanding_invoices", "List unpaid invoices. Param: limit (default 20).", ["limit"], _outstanding_invoices),
268
269
  ToolDef("top_items_by_value", "List items ranked by total inventory value. Param: limit (default 10).", ["limit"], _top_items_by_value),
269
270
  ToolDef("active_deals_summary", "Summarise the CRM pipeline - open deals by stage with count and total value.", [], _active_deals_summary),
@@ -273,6 +273,176 @@ def _test_db(db_url: str) -> str | None:
273
273
  return str(e)
274
274
 
275
275
 
276
+ # ── Database mode resolution (external vs embedded) ────────────────────────────
277
+ #
278
+ # `celerp init` supports two ways to reach Postgres:
279
+ # external — a PostgreSQL server the user (or the droplet/apt) already runs.
280
+ # embedded — a self-contained cluster we boot from bundled binaries when the
281
+ # user has no server. See celerp.embedded_pg.
282
+ # The rule is "an existing server always wins": embedded is only a fallback so
283
+ # a machine with a real Postgres never ends up with two postmasters.
284
+
285
+
286
+ def _is_root() -> bool:
287
+ """True only where we can `sudo -u postgres` to provision (POSIX, uid 0).
288
+
289
+ Guarded with hasattr because os.getuid() does not exist on Windows — the old
290
+ unguarded call raised AttributeError instead of showing guidance there.
291
+ """
292
+ return hasattr(os, "getuid") and os.getuid() == 0
293
+
294
+
295
+ def _classify_probe(err: str | None) -> str:
296
+ """Map a connection attempt's outcome to server reachability.
297
+
298
+ Returns:
299
+ "ok" — connected; server up and the target DB exists.
300
+ "needs_provision" — server is up but the role/database is missing or auth
301
+ failed; external provisioning (root) can fix it.
302
+ "unreachable" — nothing is listening (connection refused / timeout).
303
+
304
+ "needs_provision" still means a server EXISTS, so init stays in external
305
+ mode rather than booting an embedded cluster beside it.
306
+ """
307
+ if err is None:
308
+ return "ok"
309
+ low = err.lower()
310
+ # Server answered, but the role/db isn't set up yet, or auth was rejected.
311
+ if (
312
+ "does not exist" in low
313
+ or "authentication failed" in low
314
+ or "no password supplied" in low
315
+ or "role" in low and "does not exist" in low
316
+ ):
317
+ return "needs_provision"
318
+ # Nothing accepted the connection.
319
+ return "unreachable"
320
+
321
+
322
+ def _resolve_db_mode(
323
+ *,
324
+ db_url: str | None,
325
+ server_reachable: bool | None,
326
+ provider_available: bool,
327
+ want_embedded: bool,
328
+ no_embedded: bool,
329
+ existing_embedded: bool | None = None,
330
+ ) -> tuple[str, str | None]:
331
+ """Pure decision function for `celerp init`'s database mode.
332
+
333
+ Returns (mode, error_kind) where mode is "external" | "embedded" | "error".
334
+ Kept side-effect-free so the whole branch table can be unit-tested without a
335
+ database.
336
+
337
+ Args:
338
+ db_url: explicit --db-url; taken at face value (external), never probed.
339
+ server_reachable: result of probing the default host; None when not probed.
340
+ provider_available: whether the embedded backend can run here.
341
+ want_embedded/no_embedded: the --embedded / --no-embedded overrides.
342
+ existing_embedded: the mode of an already-initialized instance (True/False),
343
+ or None for a fresh install. On `--force` this PRESERVES the instance's
344
+ mode so re-initializing an external install (e.g. a droplet) never flips
345
+ to embedded just because its server was momentarily unreachable.
346
+
347
+ Precedence: conflicting-flags → db_url → --embedded → --no-embedded →
348
+ existing config's mode → probe.
349
+ """
350
+ if want_embedded and no_embedded:
351
+ return ("error", "conflicting_flags")
352
+ if db_url and want_embedded:
353
+ # An explicit external URL and "force embedded" are contradictory.
354
+ return ("error", "db_url_with_embedded")
355
+ if db_url:
356
+ return ("external", None)
357
+ if want_embedded:
358
+ return ("embedded", None) if provider_available else ("error", "no_provider")
359
+ if no_embedded:
360
+ # User requires external. Reachable → use it; otherwise fail with external
361
+ # guidance rather than silently starting a cluster.
362
+ return ("external", None) if server_reachable else ("error", "no_server_external_only")
363
+ if existing_embedded is True:
364
+ return ("embedded", None) if provider_available else ("error", "no_provider")
365
+ if existing_embedded is False:
366
+ return ("external", None)
367
+ # Fresh install, no overrides: an existing server always wins.
368
+ if server_reachable:
369
+ return ("external", None)
370
+ if provider_available:
371
+ return ("embedded", None)
372
+ return ("error", "no_server_no_provider")
373
+
374
+
375
+ def _emit_db_error(kind: str, db_url: str) -> None:
376
+ """Print actionable guidance for a resolve/connect failure (stderr)."""
377
+ if kind == "conflicting_flags":
378
+ click.echo(" ✗ --embedded and --no-embedded are mutually exclusive.", err=True)
379
+ return
380
+ if kind == "db_url_with_embedded":
381
+ click.echo(
382
+ " ✗ --embedded cannot be combined with --db-url (which selects an "
383
+ "external server).",
384
+ err=True,
385
+ )
386
+ return
387
+ if kind == "no_provider":
388
+ click.echo(
389
+ f" ✗ Embedded PostgreSQL is not available on this platform ({sys.platform}).",
390
+ err=True,
391
+ )
392
+ click.echo(
393
+ "\nInstall PostgreSQL and re-run, or use a supported platform "
394
+ "(Linux x86_64/arm64 — glibc or musl — or Windows x64).",
395
+ err=True,
396
+ )
397
+ if sys.platform == "darwin":
398
+ click.echo(
399
+ "On macOS 26 or newer: pip install celerp-postgres — then re-run "
400
+ "`celerp init` for the bundled database.",
401
+ err=True,
402
+ )
403
+ return
404
+ # no_server_external_only / no_server_no_provider: nothing was listening.
405
+ click.echo(f" ✗ No PostgreSQL server found at {db_url}.", err=True)
406
+ if kind == "no_server_external_only":
407
+ click.echo(
408
+ "\n--no-embedded was set, so no cluster was started. Install and start "
409
+ "PostgreSQL, then re-run `celerp init`.",
410
+ err=True,
411
+ )
412
+ return
413
+ # no_server_no_provider — embedded unavailable AND no server.
414
+ click.echo(
415
+ "\nInstall PostgreSQL and start it, then re-run `celerp init` — or use a "
416
+ "supported platform (Linux x86_64/arm64 — glibc or musl — or Windows x64) "
417
+ "to get the bundled database automatically.",
418
+ err=True,
419
+ )
420
+ if sys.platform.startswith("linux"):
421
+ click.echo(" e.g. sudo apt install postgresql && sudo service postgresql start", err=True)
422
+
423
+
424
+ def ensure_database(cfg: dict) -> None:
425
+ """Boot the embedded cluster for a DB-touching command, if this install uses
426
+ one, and refresh the connection URI in `cfg` in place.
427
+
428
+ No-op for external mode (never imports the embedded provider, so external
429
+ installs — including every droplet — are unaffected). Idempotent: safe to
430
+ call from every command that reads cfg["database"]["url"].
431
+ """
432
+ db = cfg.get("database", {})
433
+ if not db.get("embedded"):
434
+ return
435
+ from celerp import embedded_pg
436
+
437
+ config_dir = _config_path().parent
438
+ # Re-derive the URI on every boot rather than trusting the stored one: the
439
+ # unix-socket path lives under a runtime dir that a reboot can relocate.
440
+ db["url"] = embedded_pg.ensure_cluster(config_dir)
441
+ bd = embedded_pg.bin_dir()
442
+ if bd:
443
+ cfg.setdefault("backup", {}).setdefault("pg_bin_dir", bd)
444
+
445
+
276
446
  def _run_upgrade_with_auto_stamp(alembic_cfg, engine_url: str) -> None:
277
447
  """Run alembic upgrade head, auto-stamping past any already-applied revisions.
278
448
 
@@ -464,6 +634,103 @@ def _reconcile_after_migrate(db_url: str) -> None:
464
634
  engine.dispose()
465
635
 
466
636
 
637
+ def _wipe_attachment_dirs(purge_dirs: list) -> None:
638
+ """Remove attached-file directories on --force so a re-init is truly fresh."""
639
+ import shutil
640
+ for _d in purge_dirs:
641
+ if _d.exists():
642
+ shutil.rmtree(_d, ignore_errors=True)
643
+ click.echo(f" ✓ Removed {_d.resolve()}")
644
+
645
+
646
+ def _init_embedded(cfg: dict, config_dir: "Path", *, force: bool, purge_dirs: list) -> None:
647
+ """Provision the bundled PostgreSQL cluster and point cfg at it.
648
+
649
+ No sudo, no ownership/grant dance: the app connects as the cluster superuser
650
+ over a unix socket, so it owns every object it creates.
651
+ """
652
+ from celerp import embedded_pg
653
+
654
+ if force:
655
+ click.echo("Wiping embedded database for fresh init...")
656
+ embedded_pg.wipe(config_dir)
657
+ _wipe_attachment_dirs(purge_dirs)
658
+ click.echo(" ✓ Database ready (fresh)")
659
+
660
+ click.echo("Starting embedded PostgreSQL...")
661
+ uri = embedded_pg.ensure_cluster(config_dir)
662
+ cfg["database"]["url"] = uri
663
+ cfg["database"]["embedded"] = True
664
+ bd = embedded_pg.bin_dir()
665
+ if bd:
666
+ cfg.setdefault("backup", {})["pg_bin_dir"] = bd
667
+ click.echo(f" ✓ Using embedded PostgreSQL at {embedded_pg.pgdata_dir(config_dir)}")
668
+
669
+
670
+ def _init_external(cfg: dict, *, force: bool, db_url: str | None, purge_dirs: list) -> None:
671
+ """Connect to (and, as root, provision) an external PostgreSQL server.
672
+
673
+ This is the pre-existing path, preserved verbatim for the droplet/self-hosted
674
+ contract: explicit --db-url, root auto-provisioning via `sudo -u postgres`,
675
+ and the same connect-or-guidance flow for non-root.
676
+ """
677
+ if force:
678
+ click.echo("Wiping database for fresh init...")
679
+ db_url_for_wipe = db_url or _DEFAULT_DB_URL
680
+ try:
681
+ _provision_db(db_url_for_wipe, drop_existing=True)
682
+ except RuntimeError as e:
683
+ click.echo(f" ✗ DB wipe failed: {e}", err=True)
684
+ click.echo("\nEnsure PostgreSQL is running and you have sudo access.", err=True)
685
+ sys.exit(1)
686
+ click.echo(" ✓ Database ready (fresh)")
687
+ _wipe_attachment_dirs(purge_dirs)
688
+ return
689
+
690
+ click.echo("Connecting to database...")
691
+ err = _test_db(cfg["database"]["url"])
692
+ if not err:
693
+ click.echo(" ✓ Database connection OK")
694
+ return
695
+ if _is_root():
696
+ click.echo(" · Could not connect — attempting to provision database...")
697
+ try:
698
+ _provision_db(cfg["database"]["url"])
699
+ except RuntimeError as e:
700
+ click.echo(f" ✗ Provisioning failed: {e}", err=True)
701
+ click.echo("\nEnsure PostgreSQL is installed and running, then retry with sudo.", err=True)
702
+ sys.exit(1)
703
+ err = _test_db(cfg["database"]["url"])
704
+ if err:
705
+ click.echo(f" ✗ Still could not connect after provisioning: {err}", err=True)
706
+ sys.exit(1)
707
+ click.echo(" ✓ Database connection OK")
708
+ return
709
+ # Non-root and the server rejected us. On POSIX, sudo can provision; on
710
+ # Windows there is no `sudo -u postgres`, so only suggest it where it works.
711
+ click.echo(f" ✗ Could not connect: {err}", err=True)
712
+ import shutil
713
+ real_bin = shutil.which("celerp") or "celerp"
714
+ if hasattr(os, "getuid"):
715
+ click.echo(
716
+ f"\nRe-run with sudo to have Celerp create the database automatically:\n"
717
+ f" sudo {real_bin} init\n"
718
+ "\nOr create it manually:\n"
719
+ " sudo -u postgres psql -c \"CREATE USER celerp WITH PASSWORD 'celerp';\"\n"
720
+ " sudo -u postgres psql -c \"CREATE DATABASE celerp OWNER celerp;\"",
721
+ err=True,
722
+ )
723
+ else:
724
+ click.echo(
725
+ "\nCreate the database and role on your PostgreSQL server, then re-run "
726
+ "`celerp init --db-url ...`:\n"
727
+ " CREATE USER celerp WITH PASSWORD 'celerp';\n"
728
+ " CREATE DATABASE celerp OWNER celerp;",
729
+ err=True,
730
+ )
731
+ sys.exit(1)
732
+
733
+
467
734
  # ── Commands ──────────────────────────────────────────────────────────────────
468
735
 
469
736
  @click.group()
@@ -484,8 +751,23 @@ def main() -> None:
484
751
  "WITHOUT launching the servers. For service-managed/headless installs "
485
752
  "where a process manager (e.g. systemd) runs `celerp start`.",
486
753
  )
487
- def init(db_url, api_port, ui_port, cloud_token, force, assume_yes, no_start):
488
- """Initialize Celerp: write config and run database migrations."""
754
+ @click.option(
755
+ "--embedded", "want_embedded", is_flag=True,
756
+ help="Force the bundled PostgreSQL even if a server is reachable. "
757
+ "Cannot be combined with --db-url.",
758
+ )
759
+ @click.option(
760
+ "--no-embedded", "no_embedded", is_flag=True,
761
+ help="Never fall back to the bundled PostgreSQL; require an external server.",
762
+ )
763
+ def init(db_url, api_port, ui_port, cloud_token, force, assume_yes, no_start, want_embedded, no_embedded):
764
+ """Initialize Celerp: write config and run database migrations.
765
+
766
+ With no --db-url, init uses an existing PostgreSQL server if one is running,
767
+ and otherwise boots a self-contained bundled cluster (no sudo, no system
768
+ service). An existing server always wins; pass --embedded / --no-embedded to
769
+ override the auto-detection.
770
+ """
489
771
  config_path = _config_path()
490
772
 
491
773
  if config_path.exists() and not force:
@@ -493,16 +775,49 @@ def init(db_url, api_port, ui_port, cloud_token, force, assume_yes, no_start):
493
775
  click.echo("Run `celerp migrate` to apply updates, or `celerp init --force` to reconfigure.")
494
776
  return
495
777
 
778
+ from celerp import embedded_pg
779
+
780
+ # ── Resolve external vs embedded ──────────────────────────────────────────
781
+ # On --force, config_path exists: preserve the initialized instance's mode so
782
+ # re-init never flips an external install (e.g. a droplet) to embedded.
783
+ existing_cfg = _read_config() if config_path.exists() else {}
784
+ existing_embedded = (
785
+ bool(existing_cfg.get("database", {}).get("embedded")) if existing_cfg else None
786
+ )
787
+ provider_available = embedded_pg.is_available()
788
+ # Probe the default host only when nothing else determines the mode — an
789
+ # explicit --db-url/--embedded, or a known existing mode, needs no probe.
790
+ server_reachable: bool | None = None
791
+ need_probe = not db_url and not want_embedded and (no_embedded or existing_embedded is None)
792
+ if need_probe:
793
+ server_reachable = _classify_probe(_test_db(_DEFAULT_DB_URL)) in ("ok", "needs_provision")
794
+ mode, error_kind = _resolve_db_mode(
795
+ db_url=db_url,
796
+ server_reachable=server_reachable,
797
+ provider_available=provider_available,
798
+ want_embedded=want_embedded,
799
+ no_embedded=no_embedded,
800
+ existing_embedded=existing_embedded,
801
+ )
802
+ if mode == "error":
803
+ _emit_db_error(error_kind, db_url or _DEFAULT_DB_URL)
804
+ sys.exit(1)
805
+
806
+ config_dir = config_path.parent
807
+
496
808
  if force:
497
- # --force is destructive: it drops the database AND removes attached files.
498
- # init can run under sudo, so warn (with full paths) and confirm before wiping.
809
+ # --force is destructive: it wipes the database AND attached files.
810
+ # init can run under sudo, so warn (with full paths) and confirm first.
499
811
  from celerp.config import settings
500
812
  _purge_dirs = [
501
813
  settings.data_dir / "static" / "attachments",
502
814
  settings.data_dir / "ai_uploads",
503
815
  ]
504
816
  click.echo("⚠ `init --force` permanently WIPES this instance:")
505
- click.echo(f" - database: {db_url or _DEFAULT_DB_URL}")
817
+ if mode == "embedded":
818
+ click.echo(f" - database: embedded cluster at {embedded_pg.pgdata_dir(config_dir)}")
819
+ else:
820
+ click.echo(f" - database: {db_url or _DEFAULT_DB_URL}")
506
821
  for _d in _purge_dirs:
507
822
  click.echo(f" - files: {_d.resolve()}")
508
823
  click.echo(" Make sure you have a backup.")
@@ -523,62 +838,10 @@ def init(db_url, api_port, ui_port, cloud_token, force, assume_yes, no_start):
523
838
  "modules": {"enabled": enabled_modules},
524
839
  }
525
840
 
526
- # --force: drop + recreate the database so the setup wizard appears fresh
527
- if force:
528
- click.echo("Wiping database for fresh init...")
529
- db_url_for_wipe = db_url or _DEFAULT_DB_URL
530
- try:
531
- _provision_db(db_url_for_wipe, drop_existing=True)
532
- except RuntimeError as e:
533
- click.echo(f" ✗ DB wipe failed: {e}", err=True)
534
- click.echo(
535
- "\nEnsure PostgreSQL is running and you have sudo access.",
536
- err=True,
537
- )
538
- sys.exit(1)
539
- click.echo(" ✓ Database ready (fresh)")
540
- # Wipe attached files too, so a forced re-init is a truly fresh instance and no
541
- # orphaned files remain. Recreated automatically on next boot.
542
- import shutil
543
- for _d in _purge_dirs:
544
- if _d.exists():
545
- shutil.rmtree(_d, ignore_errors=True)
546
- click.echo(f" ✓ Removed {_d.resolve()}")
841
+ if mode == "embedded":
842
+ _init_embedded(cfg, config_dir, force=force, purge_dirs=_purge_dirs if force else [])
547
843
  else:
548
- # Test DB connection — auto-provision if running as root
549
- click.echo("Connecting to database...")
550
- err = _test_db(cfg["database"]["url"])
551
- if err:
552
- if os.getuid() == 0:
553
- click.echo(" · Could not connect — attempting to provision database...")
554
- try:
555
- _provision_db(cfg["database"]["url"])
556
- except RuntimeError as e:
557
- click.echo(f" ✗ Provisioning failed: {e}", err=True)
558
- click.echo(
559
- "\nEnsure PostgreSQL is installed and running, then retry with sudo.",
560
- err=True,
561
- )
562
- sys.exit(1)
563
- # Verify connection now works
564
- err = _test_db(cfg["database"]["url"])
565
- if err:
566
- click.echo(f" ✗ Still could not connect after provisioning: {err}", err=True)
567
- sys.exit(1)
568
- else:
569
- click.echo(f" ✗ Could not connect: {err}", err=True)
570
- import shutil
571
- real_bin = shutil.which("celerp") or "celerp"
572
- click.echo(
573
- f"\nRe-run with sudo to have Celerp create the database automatically:\n"
574
- f" sudo {real_bin} init\n"
575
- "\nOr create it manually:\n"
576
- " sudo -u postgres psql -c \"CREATE USER celerp WITH PASSWORD 'celerp';\"\n"
577
- " sudo -u postgres psql -c \"CREATE DATABASE celerp OWNER celerp;\"",
578
- err=True,
579
- )
580
- sys.exit(1)
581
- click.echo(" ✓ Database connection OK")
844
+ _init_external(cfg, force=force, db_url=db_url, purge_dirs=_purge_dirs if force else [])
582
845
 
583
846
  # Fix table ownership before migrations (covers tables created by postgres superuser)
584
847
  db_url_val = cfg["database"]["url"]
@@ -720,6 +983,7 @@ def reset_password(email: str, password: str) -> None:
720
983
  if not cfg:
721
984
  click.echo("Not initialized. Run `celerp init` first.", err=True)
722
985
  sys.exit(1)
986
+ ensure_database(cfg)
723
987
  db_url = cfg["database"]["url"]
724
988
  sync_url = db_url.replace("postgresql+asyncpg://", "postgresql://")
725
989
  try:
@@ -748,6 +1012,7 @@ def start():
748
1012
  if not cfg:
749
1013
  click.echo("Not initialized. Run `celerp init` first.", err=True)
750
1014
  sys.exit(1)
1015
+ ensure_database(cfg)
751
1016
  _start(cfg)
752
1017
 
753
1018
 
@@ -761,6 +1026,7 @@ def migrate(db_url):
761
1026
  if not cfg:
762
1027
  click.echo("Not initialized. Run `celerp init` first.", err=True)
763
1028
  sys.exit(1)
1029
+ ensure_database(cfg)
764
1030
  url = cfg["database"]["url"]
765
1031
  click.echo("Running migrations...")
766
1032
  _run_migrations(url)
@@ -780,11 +1046,14 @@ def status():
780
1046
  click.echo("Run `celerp init` to initialize.")
781
1047
  return
782
1048
 
1049
+ is_embedded = cfg.get("database", {}).get("embedded")
1050
+ ensure_database(cfg)
783
1051
  db_url = cfg["database"]["url"]
784
1052
  # Mask password in display
785
1053
  import re
786
1054
  display_url = re.sub(r"://([^:]+):([^@]+)@", r"://\1:***@", db_url)
787
- click.echo(f"Database: {display_url}")
1055
+ prefix = "embedded (bundled PostgreSQL) — " if is_embedded else ""
1056
+ click.echo(f"Database: {prefix}{display_url}")
788
1057
 
789
1058
  err = _test_db(db_url)
790
1059
  click.echo(f" DB connection: {'✓ OK' if not err else f'✗ {err}'}")
@@ -831,6 +1100,7 @@ def demo():
831
1100
  if not cfg:
832
1101
  click.echo("Not initialized. Run `celerp init` first.", err=True)
833
1102
  sys.exit(1)
1103
+ ensure_database(cfg)
834
1104
  env = _config_to_env(cfg)
835
1105
  pkg_root = Path(__file__).parent.parent
836
1106
  script = pkg_root / "scripts" / "seed_demo.py"
@@ -853,6 +1123,7 @@ def upgrade():
853
1123
  if not cfg:
854
1124
  click.echo("Not initialized. Run `celerp init` first.", err=True)
855
1125
  sys.exit(1)
1126
+ ensure_database(cfg)
856
1127
  _run_migrations(cfg["database"]["url"])
857
1128
  click.echo("✓ Upgrade complete")
858
1129