celerp 1.2.4__tar.gz → 1.2.6__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 (551) hide show
  1. {celerp-1.2.4 → celerp-1.2.6}/CONTRIBUTING.md +37 -2
  2. {celerp-1.2.4 → celerp-1.2.6}/PKG-INFO +6 -3
  3. {celerp-1.2.4 → celerp-1.2.6}/README.md +5 -2
  4. celerp-1.2.6/celerp/__main__.py +14 -0
  5. {celerp-1.2.4 → celerp-1.2.6}/celerp/ai/conversations.py +1 -1
  6. {celerp-1.2.4 → celerp-1.2.6}/celerp/cli.py +84 -11
  7. {celerp-1.2.4 → celerp-1.2.6}/celerp/config.py +5 -1
  8. {celerp-1.2.4 → celerp-1.2.6}/celerp/connectors/daily_scheduler.py +25 -1
  9. celerp-1.2.6/celerp/connectors/relay_token.py +50 -0
  10. {celerp-1.2.4 → celerp-1.2.6}/celerp/connectors/shopify.py +21 -5
  11. {celerp-1.2.4 → celerp-1.2.6}/celerp/events/engine.py +6 -0
  12. {celerp-1.2.4 → celerp-1.2.6}/celerp/gateway/client.py +46 -7
  13. {celerp-1.2.4 → celerp-1.2.6}/celerp/main.py +26 -1
  14. {celerp-1.2.4 → celerp-1.2.6}/celerp/middleware.py +7 -4
  15. celerp-1.2.6/celerp/migrations/_data_reconcile.py +113 -0
  16. {celerp-1.2.4 → celerp-1.2.6}/celerp/notifications/service.py +1 -1
  17. {celerp-1.2.4 → celerp-1.2.6}/celerp/routers/health.py +2 -5
  18. {celerp-1.2.4 → celerp-1.2.6}/celerp/routers/stars.py +7 -3
  19. {celerp-1.2.4 → celerp-1.2.6}/celerp/services/backup.py +3 -94
  20. {celerp-1.2.4 → celerp-1.2.6}/celerp/services/backup_export.py +17 -28
  21. {celerp-1.2.4 → celerp-1.2.6}/celerp/services/backup_import.py +42 -5
  22. celerp-1.2.6/celerp/services/backup_repo.py +241 -0
  23. celerp-1.2.6/celerp/services/backup_scheduler.py +107 -0
  24. celerp-1.2.6/celerp/services/backup_state.py +31 -0
  25. celerp-1.2.6/celerp/services/dev_release_guard.py +100 -0
  26. {celerp-1.2.4 → celerp-1.2.6}/celerp/services/field_schema.py +5 -0
  27. {celerp-1.2.4 → celerp-1.2.6}/celerp/services/supporter_badge.py +5 -3
  28. {celerp-1.2.4 → celerp-1.2.6}/celerp.egg-info/PKG-INFO +6 -3
  29. {celerp-1.2.4 → celerp-1.2.6}/celerp.egg-info/SOURCES.txt +9 -1
  30. {celerp-1.2.4 → celerp-1.2.6}/celerp.egg-info/scm_file_list.json +16 -2
  31. celerp-1.2.6/celerp.egg-info/scm_version.json +8 -0
  32. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-ai/celerp_ai/routes.py +2 -1
  33. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-ai/tests/test_conversations.py +30 -0
  34. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-backup/celerp_backup/routes.py +26 -37
  35. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-connectors/tests/test_connectors.py +2 -0
  36. celerp-1.2.6/default_modules/celerp-connectors/tests/test_images.py +138 -0
  37. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-connectors/tests/test_shopify.py +32 -0
  38. celerp-1.2.6/default_modules/celerp-connectors/tests/test_wiring.py +129 -0
  39. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-contacts/celerp_contacts/routes.py +3 -0
  40. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-contacts/celerp_contacts/services.py +6 -2
  41. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-docs/celerp_docs/doc_service.py +9 -8
  42. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-docs/celerp_docs/routes.py +40 -16
  43. celerp-1.2.6/default_modules/celerp-docs/tests/test_line_delete_persist.py +85 -0
  44. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-inventory/celerp_inventory/routes.py +35 -38
  45. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-subscriptions/celerp_subscriptions/routes.py +1 -1
  46. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-subscriptions/tests/test_subscriptions.py +24 -0
  47. {celerp-1.2.4 → celerp-1.2.6}/pyproject.toml +6 -0
  48. {celerp-1.2.4 → celerp-1.2.6}/ui/api_client.py +49 -29
  49. {celerp-1.2.4 → celerp-1.2.6}/ui/app.py +15 -7
  50. {celerp-1.2.4 → celerp-1.2.6}/ui/components/activity.py +60 -2
  51. {celerp-1.2.4 → celerp-1.2.6}/ui/components/backup.py +5 -15
  52. {celerp-1.2.4 → celerp-1.2.6}/ui/components/shell.py +96 -7
  53. {celerp-1.2.4 → celerp-1.2.6}/ui/components/table.py +31 -10
  54. {celerp-1.2.4 → celerp-1.2.6}/ui/locales/ar.json +1 -7
  55. {celerp-1.2.4 → celerp-1.2.6}/ui/locales/de.json +1 -7
  56. {celerp-1.2.4 → celerp-1.2.6}/ui/locales/en.json +3 -7
  57. {celerp-1.2.4 → celerp-1.2.6}/ui/locales/es.json +1 -7
  58. {celerp-1.2.4 → celerp-1.2.6}/ui/locales/fr.json +1 -7
  59. {celerp-1.2.4 → celerp-1.2.6}/ui/locales/id.json +1 -7
  60. {celerp-1.2.4 → celerp-1.2.6}/ui/locales/it.json +1 -7
  61. {celerp-1.2.4 → celerp-1.2.6}/ui/locales/ja.json +1 -7
  62. {celerp-1.2.4 → celerp-1.2.6}/ui/locales/pt.json +1 -7
  63. {celerp-1.2.4 → celerp-1.2.6}/ui/locales/th.json +1 -7
  64. {celerp-1.2.4 → celerp-1.2.6}/ui/locales/vi.json +1 -7
  65. {celerp-1.2.4 → celerp-1.2.6}/ui/routes/auth.py +6 -2
  66. {celerp-1.2.4 → celerp-1.2.6}/ui/routes/dashboard.py +1 -1
  67. {celerp-1.2.4 → celerp-1.2.6}/ui/routes/documents.py +39 -19
  68. {celerp-1.2.4 → celerp-1.2.6}/ui/routes/inventory.py +18 -18
  69. {celerp-1.2.4 → celerp-1.2.6}/ui/routes/settings.py +78 -75
  70. {celerp-1.2.4 → celerp-1.2.6}/ui/routes/settings_cloud.py +0 -2
  71. celerp-1.2.4/celerp/services/backup_files.py +0 -181
  72. celerp-1.2.4/celerp/services/backup_scheduler.py +0 -171
  73. celerp-1.2.4/celerp.egg-info/scm_version.json +0 -8
  74. {celerp-1.2.4 → celerp-1.2.6}/CLA.md +0 -0
  75. {celerp-1.2.4 → celerp-1.2.6}/LICENSE +0 -0
  76. {celerp-1.2.4 → celerp-1.2.6}/LICENSING.md +0 -0
  77. {celerp-1.2.4 → celerp-1.2.6}/MANIFEST.in +0 -0
  78. {celerp-1.2.4 → celerp-1.2.6}/NOTICE +0 -0
  79. {celerp-1.2.4 → celerp-1.2.6}/alembic.ini +0 -0
  80. {celerp-1.2.4 → celerp-1.2.6}/celerp/__init__.py +0 -0
  81. {celerp-1.2.4 → celerp-1.2.6}/celerp/ai/__init__.py +0 -0
  82. {celerp-1.2.4 → celerp-1.2.6}/celerp/ai/batch.py +0 -0
  83. {celerp-1.2.4 → celerp-1.2.6}/celerp/ai/cleanup.py +0 -0
  84. {celerp-1.2.4 → celerp-1.2.6}/celerp/ai/commands.py +0 -0
  85. {celerp-1.2.4 → celerp-1.2.6}/celerp/ai/files.py +0 -0
  86. {celerp-1.2.4 → celerp-1.2.6}/celerp/ai/intent.py +0 -0
  87. {celerp-1.2.4 → celerp-1.2.6}/celerp/ai/llm.py +0 -0
  88. {celerp-1.2.4 → celerp-1.2.6}/celerp/ai/memory.py +0 -0
  89. {celerp-1.2.4 → celerp-1.2.6}/celerp/ai/models.py +0 -0
  90. {celerp-1.2.4 → celerp-1.2.6}/celerp/ai/page_count.py +0 -0
  91. {celerp-1.2.4 → celerp-1.2.6}/celerp/ai/quota.py +0 -0
  92. {celerp-1.2.4 → celerp-1.2.6}/celerp/ai/service.py +0 -0
  93. {celerp-1.2.4 → celerp-1.2.6}/celerp/ai/tools.py +0 -0
  94. {celerp-1.2.4 → celerp-1.2.6}/celerp/alembic.ini +0 -0
  95. {celerp-1.2.4 → celerp-1.2.6}/celerp/alembic_config.py +0 -0
  96. {celerp-1.2.4 → celerp-1.2.6}/celerp/compute/__init__.py +0 -0
  97. {celerp-1.2.4 → celerp-1.2.6}/celerp/compute/aggregations.py +0 -0
  98. {celerp-1.2.4 → celerp-1.2.6}/celerp/compute/valuation.py +0 -0
  99. {celerp-1.2.4 → celerp-1.2.6}/celerp/connectors/__init__.py +0 -0
  100. {celerp-1.2.4 → celerp-1.2.6}/celerp/connectors/base.py +0 -0
  101. {celerp-1.2.4 → celerp-1.2.6}/celerp/connectors/http.py +0 -0
  102. {celerp-1.2.4 → celerp-1.2.6}/celerp/connectors/images.py +0 -0
  103. {celerp-1.2.4 → celerp-1.2.6}/celerp/connectors/outbound_queue.py +0 -0
  104. {celerp-1.2.4 → celerp-1.2.6}/celerp/connectors/quickbooks.py +0 -0
  105. {celerp-1.2.4 → celerp-1.2.6}/celerp/connectors/registry.py +0 -0
  106. {celerp-1.2.4 → celerp-1.2.6}/celerp/connectors/sync_runner.py +0 -0
  107. {celerp-1.2.4 → celerp-1.2.6}/celerp/connectors/upsert.py +0 -0
  108. {celerp-1.2.4 → celerp-1.2.6}/celerp/connectors/webhooks.py +0 -0
  109. {celerp-1.2.4 → celerp-1.2.6}/celerp/connectors/woocommerce.py +0 -0
  110. {celerp-1.2.4 → celerp-1.2.6}/celerp/connectors/xero.py +0 -0
  111. {celerp-1.2.4 → celerp-1.2.6}/celerp/constants.py +0 -0
  112. {celerp-1.2.4 → celerp-1.2.6}/celerp/db.py +0 -0
  113. {celerp-1.2.4 → celerp-1.2.6}/celerp/events/__init__.py +0 -0
  114. {celerp-1.2.4 → celerp-1.2.6}/celerp/events/schemas.py +0 -0
  115. {celerp-1.2.4 → celerp-1.2.6}/celerp/events/types.py +0 -0
  116. {celerp-1.2.4 → celerp-1.2.6}/celerp/gateway/__init__.py +0 -0
  117. {celerp-1.2.4 → celerp-1.2.6}/celerp/gateway/state.py +0 -0
  118. {celerp-1.2.4 → celerp-1.2.6}/celerp/importers/__init__.py +0 -0
  119. {celerp-1.2.4 → celerp-1.2.6}/celerp/importers/importer.py +0 -0
  120. {celerp-1.2.4 → celerp-1.2.6}/celerp/importers/schema.py +0 -0
  121. {celerp-1.2.4 → celerp-1.2.6}/celerp/migrations/README.md +0 -0
  122. {celerp-1.2.4 → celerp-1.2.6}/celerp/migrations/_auto_stamp.py +0 -0
  123. {celerp-1.2.4 → celerp-1.2.6}/celerp/migrations/env.py +0 -0
  124. {celerp-1.2.4 → celerp-1.2.6}/celerp/migrations/script.py.mako +0 -0
  125. {celerp-1.2.4 → celerp-1.2.6}/celerp/migrations/versions/a0b1c2d3e4f5_seed_landed_cost_clearing_accounts.py +0 -0
  126. {celerp-1.2.4 → celerp-1.2.6}/celerp/migrations/versions/a1b2c3d4e5f6_add_doc_share_tokens.py +0 -0
  127. {celerp-1.2.4 → celerp-1.2.6}/celerp/migrations/versions/b1c2d3e4f5a6_add_supporter_badges.py +0 -0
  128. {celerp-1.2.4 → celerp-1.2.6}/celerp/migrations/versions/b2c3d4e5f6a7_add_import_batches.py +0 -0
  129. {celerp-1.2.4 → celerp-1.2.6}/celerp/migrations/versions/c1d2e3f4a5b6_add_marketplace.py +0 -0
  130. {celerp-1.2.4 → celerp-1.2.6}/celerp/migrations/versions/d2e3f4a5b6c7_add_password_reset_token.py +0 -0
  131. {celerp-1.2.4 → celerp-1.2.6}/celerp/migrations/versions/e3f4a5b6c7d8_add_company_is_active.py +0 -0
  132. {celerp-1.2.4 → celerp-1.2.6}/celerp/migrations/versions/f1a2b3c4d5e6_move_accounts_marketplace_to_modules.py +0 -0
  133. {celerp-1.2.4 → celerp-1.2.6}/celerp/migrations/versions/fd5de461e14e_initial_schema.py +0 -0
  134. {celerp-1.2.4 → celerp-1.2.6}/celerp/migrations/versions/g1h2i3j4k5l6_add_consignment_flag.py +0 -0
  135. {celerp-1.2.4 → celerp-1.2.6}/celerp/migrations/versions/h2i3j4k5l6m7_add_bank_accounts_and_reconciliation.py +0 -0
  136. {celerp-1.2.4 → celerp-1.2.6}/celerp/migrations/versions/j4k5l6m7n8o9_labels_db_persistence.py +0 -0
  137. {celerp-1.2.4 → celerp-1.2.6}/celerp/migrations/versions/k5l6m7n8o9p0_add_reconciliation_v2.py +0 -0
  138. {celerp-1.2.4 → celerp-1.2.6}/celerp/migrations/versions/l6m7n8o9p0q1_add_sync_runs_table.py +0 -0
  139. {celerp-1.2.4 → celerp-1.2.6}/celerp/migrations/versions/m7n8o9p0q1r2_add_connector_configs_and_outbound_queue.py +0 -0
  140. {celerp-1.2.4 → celerp-1.2.6}/celerp/migrations/versions/n8o9p0q1r2s3_backfill_payment_date.py +0 -0
  141. {celerp-1.2.4 → celerp-1.2.6}/celerp/migrations/versions/o9p0q1r2s3t4_backfill_item_price_fields.py +0 -0
  142. {celerp-1.2.4 → celerp-1.2.6}/celerp/migrations/versions/p1q2r3s4t5u6_add_session_registry_and_user_auth_state.py +0 -0
  143. {celerp-1.2.4 → celerp-1.2.6}/celerp/migrations/versions/q2r3s4t5u6v7_add_system_runtime_state.py +0 -0
  144. {celerp-1.2.4 → celerp-1.2.6}/celerp/migrations/versions/r3s4t5u6v7w8_add_projections_company_entity_type_index.py +0 -0
  145. {celerp-1.2.4 → celerp-1.2.6}/celerp/migrations/versions/s4t5u6v7w8x9_drop_user_company_id_role.py +0 -0
  146. {celerp-1.2.4 → celerp-1.2.6}/celerp/migrations/versions/t5u6v7w8x9y0_seed_inventory_sub_accounts.py +0 -0
  147. {celerp-1.2.4 → celerp-1.2.6}/celerp/migrations/versions/u6v7w8x9y0z1_backfill_item_prices_from_attributes.py +0 -0
  148. {celerp-1.2.4 → celerp-1.2.6}/celerp/migrations/versions/v7w8x9y0z1a2_backfill_purchase_unit_defaults.py +0 -0
  149. {celerp-1.2.4 → celerp-1.2.6}/celerp/migrations/versions/w8x9y0z1a2b3_backfill_category_unit_defaults.py +0 -0
  150. {celerp-1.2.4 → celerp-1.2.6}/celerp/migrations/versions/x7y8z9a0b1c2_add_projection_created_at.py +0 -0
  151. {celerp-1.2.4 → celerp-1.2.6}/celerp/migrations/versions/y8z9a0b1c2d3_per_company_ledger_idempotency.py +0 -0
  152. {celerp-1.2.4 → celerp-1.2.6}/celerp/migrations/versions/z9a0b1c2d3e4_work_centers.py +0 -0
  153. {celerp-1.2.4 → celerp-1.2.6}/celerp/models/__init__.py +0 -0
  154. {celerp-1.2.4 → celerp-1.2.6}/celerp/models/accounting.py +0 -0
  155. {celerp-1.2.4 → celerp-1.2.6}/celerp/models/ai.py +0 -0
  156. {celerp-1.2.4 → celerp-1.2.6}/celerp/models/auth.py +0 -0
  157. {celerp-1.2.4 → celerp-1.2.6}/celerp/models/base.py +0 -0
  158. {celerp-1.2.4 → celerp-1.2.6}/celerp/models/company.py +0 -0
  159. {celerp-1.2.4 → celerp-1.2.6}/celerp/models/connector_config.py +0 -0
  160. {celerp-1.2.4 → celerp-1.2.6}/celerp/models/import_batch.py +0 -0
  161. {celerp-1.2.4 → celerp-1.2.6}/celerp/models/ledger.py +0 -0
  162. {celerp-1.2.4 → celerp-1.2.6}/celerp/models/marketplace.py +0 -0
  163. {celerp-1.2.4 → celerp-1.2.6}/celerp/models/notification.py +0 -0
  164. {celerp-1.2.4 → celerp-1.2.6}/celerp/models/projections.py +0 -0
  165. {celerp-1.2.4 → celerp-1.2.6}/celerp/models/share.py +0 -0
  166. {celerp-1.2.4 → celerp-1.2.6}/celerp/models/supporter.py +0 -0
  167. {celerp-1.2.4 → celerp-1.2.6}/celerp/models/sync_run.py +0 -0
  168. {celerp-1.2.4 → celerp-1.2.6}/celerp/modules/__init__.py +0 -0
  169. {celerp-1.2.4 → celerp-1.2.6}/celerp/modules/api.py +0 -0
  170. {celerp-1.2.4 → celerp-1.2.6}/celerp/modules/audit.py +0 -0
  171. {celerp-1.2.4 → celerp-1.2.6}/celerp/modules/license.py +0 -0
  172. {celerp-1.2.4 → celerp-1.2.6}/celerp/modules/loader.py +0 -0
  173. {celerp-1.2.4 → celerp-1.2.6}/celerp/modules/references.py +0 -0
  174. {celerp-1.2.4 → celerp-1.2.6}/celerp/modules/registry.py +0 -0
  175. {celerp-1.2.4 → celerp-1.2.6}/celerp/modules/slots.py +0 -0
  176. {celerp-1.2.4 → celerp-1.2.6}/celerp/notifications/__init__.py +0 -0
  177. {celerp-1.2.4 → celerp-1.2.6}/celerp/notifications/sse.py +0 -0
  178. {celerp-1.2.4 → celerp-1.2.6}/celerp/output/__init__.py +0 -0
  179. {celerp-1.2.4 → celerp-1.2.6}/celerp/output/pdf.py +0 -0
  180. {celerp-1.2.4 → celerp-1.2.6}/celerp/output/share_render.py +0 -0
  181. {celerp-1.2.4 → celerp-1.2.6}/celerp/projections/__init__.py +0 -0
  182. {celerp-1.2.4 → celerp-1.2.6}/celerp/projections/engine.py +0 -0
  183. {celerp-1.2.4 → celerp-1.2.6}/celerp/projections/handlers/__init__.py +0 -0
  184. {celerp-1.2.4 → celerp-1.2.6}/celerp/projections/handlers/marketplace.py +0 -0
  185. {celerp-1.2.4 → celerp-1.2.6}/celerp/projections/handlers/scanning.py +0 -0
  186. {celerp-1.2.4 → celerp-1.2.6}/celerp/projections/handlers/system.py +0 -0
  187. {celerp-1.2.4 → celerp-1.2.6}/celerp/routers/__init__.py +0 -0
  188. {celerp-1.2.4 → celerp-1.2.6}/celerp/routers/auth.py +0 -0
  189. {celerp-1.2.4 → celerp-1.2.6}/celerp/routers/companies.py +0 -0
  190. {celerp-1.2.4 → celerp-1.2.6}/celerp/routers/debug.py +0 -0
  191. {celerp-1.2.4 → celerp-1.2.6}/celerp/routers/doctor.py +0 -0
  192. {celerp-1.2.4 → celerp-1.2.6}/celerp/routers/events.py +0 -0
  193. {celerp-1.2.4 → celerp-1.2.6}/celerp/routers/ledger.py +0 -0
  194. {celerp-1.2.4 → celerp-1.2.6}/celerp/routers/notifications.py +0 -0
  195. {celerp-1.2.4 → celerp-1.2.6}/celerp/routers/system.py +0 -0
  196. {celerp-1.2.4 → celerp-1.2.6}/celerp/schemas/__init__.py +0 -0
  197. {celerp-1.2.4 → celerp-1.2.6}/celerp/services/__init__.py +0 -0
  198. {celerp-1.2.4 → celerp-1.2.6}/celerp/services/activity_redaction.py +0 -0
  199. {celerp-1.2.4 → celerp-1.2.6}/celerp/services/attachments.py +0 -0
  200. {celerp-1.2.4 → celerp-1.2.6}/celerp/services/auth.py +0 -0
  201. {celerp-1.2.4 → celerp-1.2.6}/celerp/services/auto_je.py +0 -0
  202. {celerp-1.2.4 → celerp-1.2.6}/celerp/services/demo.py +0 -0
  203. {celerp-1.2.4 → celerp-1.2.6}/celerp/services/email.py +0 -0
  204. {celerp-1.2.4 → celerp-1.2.6}/celerp/services/fulfill.py +0 -0
  205. {celerp-1.2.4 → celerp-1.2.6}/celerp/services/je_keys.py +0 -0
  206. {celerp-1.2.4 → celerp-1.2.6}/celerp/services/landed_cost.py +0 -0
  207. {celerp-1.2.4 → celerp-1.2.6}/celerp/services/line_measures.py +0 -0
  208. {celerp-1.2.4 → celerp-1.2.6}/celerp/services/list_behavior.py +0 -0
  209. {celerp-1.2.4 → celerp-1.2.6}/celerp/services/money.py +0 -0
  210. {celerp-1.2.4 → celerp-1.2.6}/celerp/services/pick.py +0 -0
  211. {celerp-1.2.4 → celerp-1.2.6}/celerp/services/runtime_state.py +0 -0
  212. {celerp-1.2.4 → celerp-1.2.6}/celerp/services/session_tracker.py +0 -0
  213. {celerp-1.2.4 → celerp-1.2.6}/celerp/services/star_cta.py +0 -0
  214. {celerp-1.2.4 → celerp-1.2.6}/celerp/services/system_health.py +0 -0
  215. {celerp-1.2.4 → celerp-1.2.6}/celerp/services/units.py +0 -0
  216. {celerp-1.2.4 → celerp-1.2.6}/celerp/session_gate.py +0 -0
  217. {celerp-1.2.4 → celerp-1.2.6}/celerp/tax_regimes.py +0 -0
  218. {celerp-1.2.4 → celerp-1.2.6}/celerp.egg-info/dependency_links.txt +0 -0
  219. {celerp-1.2.4 → celerp-1.2.6}/celerp.egg-info/entry_points.txt +0 -0
  220. {celerp-1.2.4 → celerp-1.2.6}/celerp.egg-info/requires.txt +0 -0
  221. {celerp-1.2.4 → celerp-1.2.6}/celerp.egg-info/top_level.txt +0 -0
  222. {celerp-1.2.4 → celerp-1.2.6}/conftest.py +0 -0
  223. {celerp-1.2.4 → celerp-1.2.6}/default_modules/__init__.py +0 -0
  224. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-accounting/LICENSE +0 -0
  225. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-accounting/__init__.py +0 -0
  226. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-accounting/celerp_accounting/__init__.py +0 -0
  227. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-accounting/celerp_accounting/api_setup.py +0 -0
  228. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-accounting/celerp_accounting/csv_parser.py +0 -0
  229. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-accounting/celerp_accounting/matcher.py +0 -0
  230. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-accounting/celerp_accounting/models.py +0 -0
  231. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-accounting/celerp_accounting/projections.py +0 -0
  232. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-accounting/celerp_accounting/routes.py +0 -0
  233. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-accounting/celerp_accounting/ui_routes.py +0 -0
  234. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-accounting/tests/test_accounting_banking.py +0 -0
  235. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-accounting/tests/test_accounting_banking_routers.py +0 -0
  236. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-accounting/tests/test_accounting_gaps.py +0 -0
  237. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-accounting/tests/test_accounting_import_idempotency.py +0 -0
  238. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-accounting/tests/test_reconciliation_v2.py +0 -0
  239. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-admin/__init__.py +0 -0
  240. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-admin/celerp_admin/__init__.py +0 -0
  241. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-admin/celerp_admin/routes.py +0 -0
  242. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-admin/celerp_admin/setup.py +0 -0
  243. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-ai/__init__.py +0 -0
  244. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-ai/celerp_ai/__init__.py +0 -0
  245. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-ai/celerp_ai/setup.py +0 -0
  246. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-ai/celerp_ai/ui_routes.py +0 -0
  247. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-ai/tests/conftest.py +0 -0
  248. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-ai/tests/test_batch.py +0 -0
  249. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-ai/tests/test_cleanup.py +0 -0
  250. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-ai/tests/test_coverage_gaps.py +0 -0
  251. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-ai/tests/test_intent.py +0 -0
  252. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-ai/tests/test_llm.py +0 -0
  253. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-ai/tests/test_memory.py +0 -0
  254. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-ai/tests/test_models.py +0 -0
  255. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-ai/tests/test_page_count.py +0 -0
  256. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-ai/tests/test_quota.py +0 -0
  257. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-ai/tests/test_router.py +0 -0
  258. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-ai/tests/test_routes_coverage.py +0 -0
  259. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-ai/tests/test_service.py +0 -0
  260. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-ai/tests/test_tools.py +0 -0
  261. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-backup/__init__.py +0 -0
  262. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-backup/celerp_backup/__init__.py +0 -0
  263. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-backup/celerp_backup/setup.py +0 -0
  264. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-connectors/__init__.py +0 -0
  265. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-connectors/celerp_connectors/__init__.py +0 -0
  266. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-connectors/celerp_connectors/models.py +0 -0
  267. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-connectors/celerp_connectors/routes.py +0 -0
  268. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-connectors/tests/__init__.py +0 -0
  269. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-connectors/tests/conftest.py +0 -0
  270. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-connectors/tests/test_compliance.py +0 -0
  271. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-connectors/tests/test_outbound.py +0 -0
  272. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-connectors/tests/test_quickbooks.py +0 -0
  273. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-connectors/tests/test_rate_limiting.py +0 -0
  274. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-connectors/tests/test_woocommerce.py +0 -0
  275. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-connectors/tests/test_xero.py +0 -0
  276. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-contacts/LICENSE +0 -0
  277. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-contacts/__init__.py +0 -0
  278. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-contacts/celerp_contacts/__init__.py +0 -0
  279. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-contacts/celerp_contacts/migrations.py +0 -0
  280. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-contacts/celerp_contacts/projections.py +0 -0
  281. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-contacts/celerp_contacts/ui_routes.py +0 -0
  282. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-dashboard/LICENSE +0 -0
  283. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-dashboard/__init__.py +0 -0
  284. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-dashboard/celerp_dashboard/__init__.py +0 -0
  285. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-dashboard/celerp_dashboard/routes.py +0 -0
  286. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-dashboard/celerp_dashboard/setup.py +0 -0
  287. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-docs/LICENSE +0 -0
  288. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-docs/__init__.py +0 -0
  289. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-docs/celerp_docs/__init__.py +0 -0
  290. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-docs/celerp_docs/api_setup.py +0 -0
  291. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-docs/celerp_docs/doc_constants.py +0 -0
  292. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-docs/celerp_docs/doc_projections.py +0 -0
  293. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-docs/celerp_docs/models_share.py +0 -0
  294. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-docs/celerp_docs/routes_share.py +0 -0
  295. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-docs/celerp_docs/sequences.py +0 -0
  296. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-docs/celerp_docs/taxes.py +0 -0
  297. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-docs/celerp_docs/ui_routes.py +0 -0
  298. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-docs/tests/conftest.py +0 -0
  299. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-docs/tests/test_audits.py +0 -0
  300. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-docs/tests/test_freight_je.py +0 -0
  301. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-docs/tests/test_freight_lines.py +0 -0
  302. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-docs/tests/test_fulfill_no_split.py +0 -0
  303. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-docs/tests/test_fulfillment_activity.py +0 -0
  304. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-docs/tests/test_inbound_je_lifecycle.py +0 -0
  305. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-docs/tests/test_inventory_account_reconciliation.py +0 -0
  306. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-docs/tests/test_landed_receive.py +0 -0
  307. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-docs/tests/test_payment_void_activity.py +0 -0
  308. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-docs/tests/test_send_visibility.py +0 -0
  309. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-docs/tests/test_service_lines.py +0 -0
  310. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-inventory/LICENSE +0 -0
  311. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-inventory/__init__.py +0 -0
  312. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-inventory/celerp_inventory/__init__.py +0 -0
  313. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-inventory/celerp_inventory/models_import_batch.py +0 -0
  314. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-inventory/celerp_inventory/projections.py +0 -0
  315. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-inventory/celerp_inventory/routes_attachments.py +0 -0
  316. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-inventory/celerp_inventory/routes_scanning.py +0 -0
  317. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-inventory/celerp_inventory/services.py +0 -0
  318. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-inventory/celerp_inventory/ui_routes.py +0 -0
  319. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-inventory/tests/test_item_recipe_projection.py +0 -0
  320. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-inventory/tests/test_item_workflow_projection.py +0 -0
  321. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-inventory/tests/test_landed_cost_projection.py +0 -0
  322. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-labels/LICENSE +0 -0
  323. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-labels/__init__.py +0 -0
  324. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-labels/celerp_labels/__init__.py +0 -0
  325. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-labels/celerp_labels/migrations/__init__.py +0 -0
  326. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-labels/celerp_labels/migrations/labels_001_create_label_templates.py +0 -0
  327. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-labels/celerp_labels/models.py +0 -0
  328. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-labels/celerp_labels/presets.py +0 -0
  329. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-labels/celerp_labels/routes.py +0 -0
  330. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-labels/celerp_labels/service.py +0 -0
  331. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-labels/celerp_labels/ui_routes.py +0 -0
  332. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-labels/requirements.txt +0 -0
  333. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-labels/tests/test_labels.py +0 -0
  334. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-labels/tests/test_labels_module.py +0 -0
  335. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-manufacturing/LICENSE +0 -0
  336. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-manufacturing/__init__.py +0 -0
  337. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-manufacturing/celerp_manufacturing/__init__.py +0 -0
  338. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-manufacturing/celerp_manufacturing/costing.py +0 -0
  339. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-manufacturing/celerp_manufacturing/expansion.py +0 -0
  340. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-manufacturing/celerp_manufacturing/labor.py +0 -0
  341. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-manufacturing/celerp_manufacturing/migrations.py +0 -0
  342. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-manufacturing/celerp_manufacturing/projection_handler.py +0 -0
  343. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-manufacturing/celerp_manufacturing/routes.py +0 -0
  344. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-manufacturing/celerp_manufacturing/ui_routes.py +0 -0
  345. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-manufacturing/requirements.txt +0 -0
  346. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-manufacturing/tests/test_bom_removed.py +0 -0
  347. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-manufacturing/tests/test_build_api.py +0 -0
  348. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-manufacturing/tests/test_item_recipe_api.py +0 -0
  349. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-manufacturing/tests/test_item_workflow_api.py +0 -0
  350. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-manufacturing/tests/test_labor_providers.py +0 -0
  351. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-manufacturing/tests/test_manufacture_from_doc.py +0 -0
  352. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-manufacturing/tests/test_manufacturing.py +0 -0
  353. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-manufacturing/tests/test_manufacturing_import_idempotency.py +0 -0
  354. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-manufacturing/tests/test_manufacturing_module.py +0 -0
  355. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-manufacturing/tests/test_mfg_events.py +0 -0
  356. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-manufacturing/tests/test_phase2_manufacturing_validations.py +0 -0
  357. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-manufacturing/tests/test_production_order.py +0 -0
  358. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-manufacturing/tests/test_recipe_costing.py +0 -0
  359. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-manufacturing/tests/test_recipe_expansion.py +0 -0
  360. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-manufacturing/tests/test_recost_api.py +0 -0
  361. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-manufacturing/tests/test_to_make_allocation.py +0 -0
  362. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-manufacturing/tests/test_where_used.py +0 -0
  363. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-manufacturing/tests/test_work_centers_and_settings.py +0 -0
  364. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-manufacturing/tests/test_workflow_time.py +0 -0
  365. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-reports/LICENSE +0 -0
  366. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-reports/__init__.py +0 -0
  367. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-reports/celerp_reports/__init__.py +0 -0
  368. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-reports/celerp_reports/api_setup.py +0 -0
  369. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-reports/celerp_reports/routes.py +0 -0
  370. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-reports/celerp_reports/ui_routes.py +0 -0
  371. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-reports/tests/test_reports_full.py +0 -0
  372. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-reports/tests/test_reports_unit.py +0 -0
  373. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-subscriptions/LICENSE +0 -0
  374. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-subscriptions/__init__.py +0 -0
  375. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-subscriptions/celerp_subscriptions/__init__.py +0 -0
  376. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-subscriptions/celerp_subscriptions/ui_routes.py +0 -0
  377. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-subscriptions/tests/test_subscriptions_ui.py +0 -0
  378. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-verticals/LICENSE +0 -0
  379. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-verticals/__init__.py +0 -0
  380. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-verticals/celerp_verticals/__init__.py +0 -0
  381. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-verticals/celerp_verticals/categories/accessory_fashion.json +0 -0
  382. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-verticals/celerp_verticals/categories/activewear.json +0 -0
  383. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-verticals/celerp_verticals/categories/art_photography.json +0 -0
  384. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-verticals/celerp_verticals/categories/audio_equipment.json +0 -0
  385. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-verticals/celerp_verticals/categories/bag_handbag.json +0 -0
  386. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-verticals/celerp_verticals/categories/banknote.json +0 -0
  387. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-verticals/celerp_verticals/categories/beauty_tool.json +0 -0
  388. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-verticals/celerp_verticals/categories/bed_bedroom.json +0 -0
  389. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-verticals/celerp_verticals/categories/beer.json +0 -0
  390. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-verticals/celerp_verticals/categories/beverage_nonalc.json +0 -0
  391. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-verticals/celerp_verticals/categories/body_part_auto.json +0 -0
  392. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-verticals/celerp_verticals/categories/book.json +0 -0
  393. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-verticals/celerp_verticals/categories/bottoms.json +0 -0
  394. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-verticals/celerp_verticals/categories/brake_suspension.json +0 -0
  395. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-verticals/celerp_verticals/categories/bullion_coin.json +0 -0
  396. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-verticals/celerp_verticals/categories/camera.json +0 -0
  397. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-verticals/celerp_verticals/categories/colored_stone.json +0 -0
  398. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-verticals/celerp_verticals/categories/comic.json +0 -0
  399. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-verticals/celerp_verticals/categories/commercial_space.json +0 -0
  400. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-verticals/celerp_verticals/categories/component_part.json +0 -0
  401. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-verticals/celerp_verticals/categories/confectionery.json +0 -0
  402. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-verticals/celerp_verticals/categories/consulting_service.json +0 -0
  403. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-verticals/celerp_verticals/categories/decorative_art.json +0 -0
  404. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-verticals/celerp_verticals/categories/diamond.json +0 -0
  405. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-verticals/celerp_verticals/categories/drawing.json +0 -0
  406. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-verticals/celerp_verticals/categories/dress_jumpsuit.json +0 -0
  407. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-verticals/celerp_verticals/categories/electrical_auto.json +0 -0
  408. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-verticals/celerp_verticals/categories/electrical_component.json +0 -0
  409. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-verticals/celerp_verticals/categories/emerald.json +0 -0
  410. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-verticals/celerp_verticals/categories/engine_part.json +0 -0
  411. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-verticals/celerp_verticals/categories/fastener.json +0 -0
  412. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-verticals/celerp_verticals/categories/fertilizer_chemical.json +0 -0
  413. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-verticals/celerp_verticals/categories/film_video.json +0 -0
  414. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-verticals/celerp_verticals/categories/fine_writing_instrument.json +0 -0
  415. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-verticals/celerp_verticals/categories/fluid_lubricant.json +0 -0
  416. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-verticals/celerp_verticals/categories/footwear.json +0 -0
  417. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-verticals/celerp_verticals/categories/fragrance.json +0 -0
  418. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-verticals/celerp_verticals/categories/fresh_food.json +0 -0
  419. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-verticals/celerp_verticals/categories/fresh_produce.json +0 -0
  420. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-verticals/celerp_verticals/categories/frozen_food.json +0 -0
  421. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-verticals/celerp_verticals/categories/gaming_console.json +0 -0
  422. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-verticals/celerp_verticals/categories/gold_bullion.json +0 -0
  423. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-verticals/celerp_verticals/categories/grain_cereal.json +0 -0
  424. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-verticals/celerp_verticals/categories/haircare.json +0 -0
  425. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-verticals/celerp_verticals/categories/hand_tool.json +0 -0
  426. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-verticals/celerp_verticals/categories/ingredient_bulk.json +0 -0
  427. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-verticals/celerp_verticals/categories/interior_part.json +0 -0
  428. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-verticals/celerp_verticals/categories/jewelry.json +0 -0
  429. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-verticals/celerp_verticals/categories/kitchen_dining.json +0 -0
  430. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-verticals/celerp_verticals/categories/laptop.json +0 -0
  431. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-verticals/celerp_verticals/categories/lighting.json +0 -0
  432. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-verticals/celerp_verticals/categories/livestock_feed.json +0 -0
  433. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-verticals/celerp_verticals/categories/makeup.json +0 -0
  434. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-verticals/celerp_verticals/categories/measuring_instrument.json +0 -0
  435. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-verticals/celerp_verticals/categories/medal_token.json +0 -0
  436. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-verticals/celerp_verticals/categories/mineral_specimen.json +0 -0
  437. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-verticals/celerp_verticals/categories/mobile_phone.json +0 -0
  438. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-verticals/celerp_verticals/categories/music_cd.json +0 -0
  439. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-verticals/celerp_verticals/categories/music_vinyl.json +0 -0
  440. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-verticals/celerp_verticals/categories/nail.json +0 -0
  441. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-verticals/celerp_verticals/categories/numismatic_coin.json +0 -0
  442. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-verticals/celerp_verticals/categories/outdoor_furniture.json +0 -0
  443. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-verticals/celerp_verticals/categories/outerwear.json +0 -0
  444. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-verticals/celerp_verticals/categories/packaged_food.json +0 -0
  445. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-verticals/celerp_verticals/categories/painting.json +0 -0
  446. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-verticals/celerp_verticals/categories/parking_bay.json +0 -0
  447. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-verticals/celerp_verticals/categories/pearl.json +0 -0
  448. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-verticals/celerp_verticals/categories/personal_care.json +0 -0
  449. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-verticals/celerp_verticals/categories/pipe_plumbing.json +0 -0
  450. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-verticals/celerp_verticals/categories/platinum_bullion.json +0 -0
  451. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-verticals/celerp_verticals/categories/power_tool.json +0 -0
  452. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-verticals/celerp_verticals/categories/print_edition.json +0 -0
  453. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-verticals/celerp_verticals/categories/residential_unit.json +0 -0
  454. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-verticals/celerp_verticals/categories/rough_gemstone.json +0 -0
  455. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-verticals/celerp_verticals/categories/ruby.json +0 -0
  456. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-verticals/celerp_verticals/categories/saas_plan.json +0 -0
  457. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-verticals/celerp_verticals/categories/safety_ppe.json +0 -0
  458. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-verticals/celerp_verticals/categories/sapphire.json +0 -0
  459. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-verticals/celerp_verticals/categories/sculpture.json +0 -0
  460. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-verticals/celerp_verticals/categories/seating.json +0 -0
  461. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-verticals/celerp_verticals/categories/seeds.json +0 -0
  462. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-verticals/celerp_verticals/categories/silver_bullion.json +0 -0
  463. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-verticals/celerp_verticals/categories/skincare.json +0 -0
  464. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-verticals/celerp_verticals/categories/soft_furnishing.json +0 -0
  465. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-verticals/celerp_verticals/categories/software_addon.json +0 -0
  466. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-verticals/celerp_verticals/categories/software_license.json +0 -0
  467. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-verticals/celerp_verticals/categories/spirit.json +0 -0
  468. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-verticals/celerp_verticals/categories/storage_furniture.json +0 -0
  469. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-verticals/celerp_verticals/categories/swimwear.json +0 -0
  470. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-verticals/celerp_verticals/categories/table_desk.json +0 -0
  471. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-verticals/celerp_verticals/categories/tablet.json +0 -0
  472. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-verticals/celerp_verticals/categories/tire_wheel.json +0 -0
  473. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-verticals/celerp_verticals/categories/tops.json +0 -0
  474. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-verticals/celerp_verticals/categories/trading_card.json +0 -0
  475. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-verticals/celerp_verticals/categories/tv_display.json +0 -0
  476. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-verticals/celerp_verticals/categories/video_game.json +0 -0
  477. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-verticals/celerp_verticals/categories/watch.json +0 -0
  478. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-verticals/celerp_verticals/categories/watch_strap.json +0 -0
  479. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-verticals/celerp_verticals/categories/wine.json +0 -0
  480. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-verticals/celerp_verticals/presets/agricultural.json +0 -0
  481. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-verticals/celerp_verticals/presets/artwork.json +0 -0
  482. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-verticals/celerp_verticals/presets/automotive.json +0 -0
  483. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-verticals/celerp_verticals/presets/blank.json +0 -0
  484. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-verticals/celerp_verticals/presets/books_media.json +0 -0
  485. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-verticals/celerp_verticals/presets/coins_precious_metals.json +0 -0
  486. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-verticals/celerp_verticals/presets/consulting.json +0 -0
  487. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-verticals/celerp_verticals/presets/cosmetics.json +0 -0
  488. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-verticals/celerp_verticals/presets/electronics.json +0 -0
  489. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-verticals/celerp_verticals/presets/fashion.json +0 -0
  490. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-verticals/celerp_verticals/presets/food_beverage.json +0 -0
  491. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-verticals/celerp_verticals/presets/furniture.json +0 -0
  492. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-verticals/celerp_verticals/presets/gemstones.json +0 -0
  493. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-verticals/celerp_verticals/presets/hardware.json +0 -0
  494. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-verticals/celerp_verticals/presets/property_rental.json +0 -0
  495. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-verticals/celerp_verticals/presets/saas.json +0 -0
  496. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-verticals/celerp_verticals/presets/watches.json +0 -0
  497. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-verticals/celerp_verticals/presets/wine_spirits.json +0 -0
  498. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-verticals/celerp_verticals/routes.py +0 -0
  499. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-verticals/celerp_verticals/ui_routes.py +0 -0
  500. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-verticals/tests/test_verticals.py +0 -0
  501. {celerp-1.2.4 → celerp-1.2.6}/default_modules/celerp-verticals/tests/test_verticals_routers.py +0 -0
  502. {celerp-1.2.4 → celerp-1.2.6}/legal/OFFICIAL-COMPONENTS.md +0 -0
  503. {celerp-1.2.4 → celerp-1.2.6}/legal/TRADEMARK.md +0 -0
  504. {celerp-1.2.4 → celerp-1.2.6}/memory/fix-receive-goods-bugs.md +0 -0
  505. {celerp-1.2.4 → celerp-1.2.6}/setup.cfg +0 -0
  506. {celerp-1.2.4 → celerp-1.2.6}/test_helpers.py +0 -0
  507. {celerp-1.2.4 → celerp-1.2.6}/ui/__init__.py +0 -0
  508. {celerp-1.2.4 → celerp-1.2.6}/ui/components/__init__.py +0 -0
  509. {celerp-1.2.4 → celerp-1.2.6}/ui/components/cloud_gate.py +0 -0
  510. {celerp-1.2.4 → celerp-1.2.6}/ui/components/currency.py +0 -0
  511. {celerp-1.2.4 → celerp-1.2.6}/ui/components/files.py +0 -0
  512. {celerp-1.2.4 → celerp-1.2.6}/ui/components/notes.py +0 -0
  513. {celerp-1.2.4 → celerp-1.2.6}/ui/components/phone.py +0 -0
  514. {celerp-1.2.4 → celerp-1.2.6}/ui/config.py +0 -0
  515. {celerp-1.2.4 → celerp-1.2.6}/ui/i18n.py +0 -0
  516. {celerp-1.2.4 → celerp-1.2.6}/ui/routes/__init__.py +0 -0
  517. {celerp-1.2.4 → celerp-1.2.6}/ui/routes/accounting.py +0 -0
  518. {celerp-1.2.4 → celerp-1.2.6}/ui/routes/accounting_import.py +0 -0
  519. {celerp-1.2.4 → celerp-1.2.6}/ui/routes/contacts.py +0 -0
  520. {celerp-1.2.4 → celerp-1.2.6}/ui/routes/csv_import.py +0 -0
  521. {celerp-1.2.4 → celerp-1.2.6}/ui/routes/docs_import.py +0 -0
  522. {celerp-1.2.4 → celerp-1.2.6}/ui/routes/events.py +0 -0
  523. {celerp-1.2.4 → celerp-1.2.6}/ui/routes/lists_import.py +0 -0
  524. {celerp-1.2.4 → celerp-1.2.6}/ui/routes/manufacturing.py +0 -0
  525. {celerp-1.2.4 → celerp-1.2.6}/ui/routes/notifications.py +0 -0
  526. {celerp-1.2.4 → celerp-1.2.6}/ui/routes/reconciliation.py +0 -0
  527. {celerp-1.2.4 → celerp-1.2.6}/ui/routes/reports.py +0 -0
  528. {celerp-1.2.4 → celerp-1.2.6}/ui/routes/search.py +0 -0
  529. {celerp-1.2.4 → celerp-1.2.6}/ui/routes/settings_accounting.py +0 -0
  530. {celerp-1.2.4 → celerp-1.2.6}/ui/routes/settings_connectors.py +0 -0
  531. {celerp-1.2.4 → celerp-1.2.6}/ui/routes/settings_contacts.py +0 -0
  532. {celerp-1.2.4 → celerp-1.2.6}/ui/routes/settings_general.py +0 -0
  533. {celerp-1.2.4 → celerp-1.2.6}/ui/routes/settings_import.py +0 -0
  534. {celerp-1.2.4 → celerp-1.2.6}/ui/routes/settings_inventory.py +0 -0
  535. {celerp-1.2.4 → celerp-1.2.6}/ui/routes/settings_manufacturing.py +0 -0
  536. {celerp-1.2.4 → celerp-1.2.6}/ui/routes/settings_purchasing.py +0 -0
  537. {celerp-1.2.4 → celerp-1.2.6}/ui/routes/settings_sales.py +0 -0
  538. {celerp-1.2.4 → celerp-1.2.6}/ui/routes/setup.py +0 -0
  539. {celerp-1.2.4 → celerp-1.2.6}/ui/routes/stars.py +0 -0
  540. {celerp-1.2.4 → celerp-1.2.6}/ui/routes/subscriptions.py +0 -0
  541. {celerp-1.2.4 → celerp-1.2.6}/ui/routes/subscriptions_import.py +0 -0
  542. {celerp-1.2.4 → celerp-1.2.6}/ui/static/app.css +0 -0
  543. {celerp-1.2.4 → celerp-1.2.6}/ui/static/htmx.min.js +0 -0
  544. {celerp-1.2.4 → celerp-1.2.6}/ui/static/icon.png +0 -0
  545. {celerp-1.2.4 → celerp-1.2.6}/ui/static/logo.png +0 -0
  546. {celerp-1.2.4 → celerp-1.2.6}/ui/static/vendor/intl-tel-input/img/flags.webp +0 -0
  547. {celerp-1.2.4 → celerp-1.2.6}/ui/static/vendor/intl-tel-input/img/flags@2x.webp +0 -0
  548. {celerp-1.2.4 → celerp-1.2.6}/ui/static/vendor/intl-tel-input/intlTelInput.min.css +0 -0
  549. {celerp-1.2.4 → celerp-1.2.6}/ui/static/vendor/intl-tel-input/intlTelInput.min.js +0 -0
  550. {celerp-1.2.4 → celerp-1.2.6}/ui/static/vendor/intl-tel-input/intlTelInputWithUtils.min.js +0 -0
  551. {celerp-1.2.4 → celerp-1.2.6}/ui/static/vendor/intl-tel-input/utils.js +0 -0
@@ -39,8 +39,9 @@ Trademarks are not licensed by any code license; see `legal/TRADEMARK.md`.
39
39
  ## CLI commands (pip install)
40
40
 
41
41
  ```bash
42
- celerp init # first-time setup (connects DB, runs migrations, writes config)
43
- celerp start # launches API + UI
42
+ celerp init # first-time setup: DB + migrations + config, then launches the servers
43
+ celerp init --no-start # same setup, but exit WITHOUT launching (service-managed/headless)
44
+ celerp start # launch API + UI (e.g. from systemd, after `init --no-start`)
44
45
  celerp migrate # apply pending migrations after an upgrade
45
46
  celerp status # show config, DB connection, migration state
46
47
  celerp demo # seed demo data
@@ -56,9 +57,43 @@ celerp upgrade # pip install --upgrade celerp + migrate
56
57
  | `--ui-port` | `8080` | UI server port |
57
58
  | `--cloud-token` | _(empty)_ | Celerp Cloud token (optional) |
58
59
  | `--force` | off | Overwrite existing config |
60
+ | `--yes` / `-y` | off | Skip the `--force` wipe confirmation (non-interactive) |
61
+ | `--no-start` | off | Set up, then exit WITHOUT launching servers (service-managed/headless) |
59
62
 
60
63
  To change ports after init, edit `~/.config/celerp/config.toml` directly.
61
64
 
65
+ ### Run as a service (systemd)
66
+
67
+ `celerp init` launches the servers and blocks (good for the one-command desktop
68
+ flow). For a headless box where a process manager owns the lifecycle, set up with
69
+ `--no-start` and let systemd run `celerp start`:
70
+
71
+ ```bash
72
+ # First boot: provision DB + migrations + config, then exit (do not block).
73
+ sudo celerp init --no-start \
74
+ --db-url "postgresql+asyncpg://celerp:<password>@localhost:5432/celerp" \
75
+ --api-port 8000 --ui-port 8080
76
+ ```
77
+
78
+ ```ini
79
+ # /etc/systemd/system/celerp.service
80
+ [Unit]
81
+ Description=Celerp
82
+ After=network.target postgresql.service
83
+
84
+ [Service]
85
+ ExecStart=/usr/local/bin/celerp start
86
+ Restart=on-failure
87
+ User=celerp
88
+
89
+ [Install]
90
+ WantedBy=multi-user.target
91
+ ```
92
+
93
+ ```bash
94
+ sudo systemctl enable --now celerp
95
+ ```
96
+
62
97
  ## Troubleshooting
63
98
 
64
99
  | Error | Fix |
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: celerp
3
- Version: 1.2.4
3
+ Version: 1.2.6
4
4
  Summary: Free, self-hosted ERP for small businesses
5
5
  License: Business Source License 1.1
6
6
 
@@ -214,13 +214,16 @@ Or install via pip:
214
214
 
215
215
  ```bash
216
216
  pip install celerp
217
- celerp init
218
- celerp start
217
+ celerp init # sets up the database and launches Celerp
219
218
  ```
220
219
 
221
220
  Open **http://localhost:8080**. Done.
222
221
  Your office can securely access the system at your IP address :8080.
223
222
 
223
+ Running headless or under a process manager? Use `celerp init --no-start` to set up
224
+ without launching, then have your service run `celerp start` — see
225
+ [Run as a service (systemd)](CONTRIBUTING.md#run-as-a-service-systemd).
226
+
224
227
  ---
225
228
 
226
229
  ## What's inside
@@ -43,13 +43,16 @@ Or install via pip:
43
43
 
44
44
  ```bash
45
45
  pip install celerp
46
- celerp init
47
- celerp start
46
+ celerp init # sets up the database and launches Celerp
48
47
  ```
49
48
 
50
49
  Open **http://localhost:8080**. Done.
51
50
  Your office can securely access the system at your IP address :8080.
52
51
 
52
+ Running headless or under a process manager? Use `celerp init --no-start` to set up
53
+ without launching, then have your service run `celerp start` — see
54
+ [Run as a service (systemd)](CONTRIBUTING.md#run-as-a-service-systemd).
55
+
53
56
  ---
54
57
 
55
58
  ## What's inside
@@ -0,0 +1,14 @@
1
+ # Copyright (c) 2026 Noah Severs
2
+ # SPDX-License-Identifier: BUSL-1.1
3
+ """Module entrypoint so `python -m celerp <command>` runs the CLI.
4
+
5
+ The packaged Electron launcher invokes the bundled Python by module
6
+ (`python -m celerp migrate`) rather than via the `celerp` console script,
7
+ which is not on PATH inside the app bundle. This mirrors `python -m alembic`.
8
+ """
9
+ from __future__ import annotations
10
+
11
+ from celerp.cli import main
12
+
13
+ if __name__ == "__main__":
14
+ main()
@@ -82,7 +82,7 @@ async def list_conversations(
82
82
  AIConversation.company_id == company_id,
83
83
  AIConversation.user_id == user_id,
84
84
  )
85
- .order_by(AIConversation.updated_at.desc())
85
+ .order_by(AIConversation.updated_at.desc(), AIConversation.id.desc()) # id tiebreaker → stable pagination
86
86
  .limit(limit)
87
87
  .offset(offset)
88
88
  )
@@ -418,6 +418,42 @@ def _run_migrations(db_url: str) -> None:
418
418
  sys.exit(1)
419
419
 
420
420
 
421
+ def _reconcile_after_migrate(db_url: str) -> None:
422
+ """Replay data-backfill migrations the auto-stamp walker skips on a develop
423
+ (create_all) database, so a develop→release in-place upgrade preserves data.
424
+
425
+ Gated by an instance_meta marker so it runs once per version; the backfills
426
+ are idempotent, so a redundant run would be a no-op anyway. The projection
427
+ rebuild (the other half of the version-change reconcile) runs in the API
428
+ lifespan, where module projection handlers are loaded.
429
+ """
430
+ import sqlalchemy as _sa
431
+
432
+ from celerp import __version__
433
+ from celerp.migrations._data_reconcile import (
434
+ BACKFILL_VERSION_KEY,
435
+ get_meta,
436
+ replay_data_backfills,
437
+ set_meta,
438
+ )
439
+
440
+ sync_url = (
441
+ db_url.replace("postgresql+asyncpg://", "postgresql://")
442
+ .replace("postgresql+psycopg2://", "postgresql://")
443
+ )
444
+ engine = _sa.create_engine(sync_url, pool_pre_ping=True)
445
+ try:
446
+ with engine.begin() as conn:
447
+ if get_meta(conn, BACKFILL_VERSION_KEY) == __version__:
448
+ return # already reconciled for this version
449
+ replayed = replay_data_backfills(conn)
450
+ set_meta(conn, BACKFILL_VERSION_KEY, __version__)
451
+ if replayed:
452
+ click.echo(f" · Reconciled {len(replayed)} data-backfill migration(s) for {__version__}")
453
+ finally:
454
+ engine.dispose()
455
+
456
+
421
457
  # ── Commands ──────────────────────────────────────────────────────────────────
422
458
 
423
459
  @click.group()
@@ -430,8 +466,15 @@ def main() -> None:
430
466
  @click.option("--api-port", default=None, type=int, help="API server port (default 8000).")
431
467
  @click.option("--ui-port", default=None, type=int, help="UI server port (default 8080).")
432
468
  @click.option("--cloud-token", default=None, help="Celerp Cloud token (optional).")
433
- @click.option("--force", is_flag=True, help="Overwrite existing config.")
434
- def init(db_url, api_port, ui_port, cloud_token, force):
469
+ @click.option("--force", is_flag=True, help="Reconfigure: WIPES the database and all attached files.")
470
+ @click.option("--yes", "-y", "assume_yes", is_flag=True, help="Skip the --force wipe confirmation (non-interactive use).")
471
+ @click.option(
472
+ "--no-start", "no_start", is_flag=True,
473
+ help="Provision the database, run migrations, and write config, then exit "
474
+ "WITHOUT launching the servers. For service-managed/headless installs "
475
+ "where a process manager (e.g. systemd) runs `celerp start`.",
476
+ )
477
+ def init(db_url, api_port, ui_port, cloud_token, force, assume_yes, no_start):
435
478
  """Initialize Celerp: write config and run database migrations."""
436
479
  config_path = _config_path()
437
480
 
@@ -441,6 +484,21 @@ def init(db_url, api_port, ui_port, cloud_token, force):
441
484
  return
442
485
 
443
486
  if force:
487
+ # --force is destructive: it drops the database AND removes attached files.
488
+ # init can run under sudo, so warn (with full paths) and confirm before wiping.
489
+ from celerp.config import settings
490
+ _purge_dirs = [
491
+ settings.data_dir / "static" / "attachments",
492
+ settings.data_dir / "ai_uploads",
493
+ ]
494
+ click.echo("⚠ `init --force` permanently WIPES this instance:")
495
+ click.echo(f" - database: {db_url or _DEFAULT_DB_URL}")
496
+ for _d in _purge_dirs:
497
+ click.echo(f" - files: {_d.resolve()}")
498
+ click.echo(" Make sure you have a backup.")
499
+ if not assume_yes and not click.confirm("Continue?", default=False):
500
+ click.echo("Aborted.")
501
+ return
444
502
  _stop_servers()
445
503
 
446
504
  enabled_modules: list[str] = []
@@ -469,6 +527,13 @@ def init(db_url, api_port, ui_port, cloud_token, force):
469
527
  )
470
528
  sys.exit(1)
471
529
  click.echo(" ✓ Database ready (fresh)")
530
+ # Wipe attached files too, so a forced re-init is a truly fresh instance and no
531
+ # orphaned files remain. Recreated automatically on next boot.
532
+ import shutil
533
+ for _d in _purge_dirs:
534
+ if _d.exists():
535
+ shutil.rmtree(_d, ignore_errors=True)
536
+ click.echo(f" ✓ Removed {_d.resolve()}")
472
537
  else:
473
538
  # Test DB connection — auto-provision if running as root
474
539
  click.echo("Connecting to database...")
@@ -549,10 +614,13 @@ def init(db_url, api_port, ui_port, cloud_token, force):
549
614
  from celerp.gateway.state import build_handoff_url as _handoff
550
615
  if _settings.star_cta_enabled:
551
616
  click.echo(
552
- "New and independent - founding supporters are how other teams find us.\n"
617
+ "New and independent - early stargazers are how other teams find us.\n"
553
618
  f" Back us early: {_handoff('/github', medium='cli')}\n"
554
619
  )
555
620
 
621
+ if no_start:
622
+ click.echo("Setup complete. Start the servers with: celerp start")
623
+ return
556
624
  _start(cfg)
557
625
 
558
626
 
@@ -674,15 +742,20 @@ def start():
674
742
 
675
743
 
676
744
  @main.command()
677
- def migrate():
678
- """Apply pending database migrations."""
679
- cfg = _read_config()
680
- if not cfg:
681
- click.echo("Not initialized. Run `celerp init` first.", err=True)
682
- sys.exit(1)
745
+ @click.option("--db-url", default=None, help="Database URL (overrides config; used by the packaged launcher).")
746
+ def migrate(db_url):
747
+ """Apply pending database migrations, then the develop→release reconcile."""
748
+ url = db_url
749
+ if url is None:
750
+ cfg = _read_config()
751
+ if not cfg:
752
+ click.echo("Not initialized. Run `celerp init` first.", err=True)
753
+ sys.exit(1)
754
+ url = cfg["database"]["url"]
683
755
  click.echo("Running migrations...")
684
- _run_migrations(cfg["database"]["url"])
685
- _post_migration_grants(cfg["database"]["url"])
756
+ _run_migrations(url)
757
+ _post_migration_grants(url)
758
+ _reconcile_after_migrate(url)
686
759
  click.echo(" ✓ Done")
687
760
 
688
761
 
@@ -20,6 +20,9 @@ class Settings(BaseSettings):
20
20
  jwt_algorithm: str = "HS256"
21
21
  access_token_expire_minutes: int = 15
22
22
  refresh_token_expire_days: int = 30
23
+ # Log the UI out after this many minutes of no user interaction (client-side idle timer).
24
+ # Uniform across direct and relay access; set to 0 to disable.
25
+ idle_logout_minutes: int = 15
23
26
  # Set to "true" to allow the default JWT secret (CI only).
24
27
  allow_insecure_jwt: str = "false"
25
28
  # Logging level for both API and UI processes. Override with LOG_LEVEL env var.
@@ -31,7 +34,8 @@ class Settings(BaseSettings):
31
34
  celerp_public_url: str = ""
32
35
  # Cloud Relay (opt-in - leave blank to disable entirely).
33
36
  # Set GATEWAY_TOKEN to activate the persistent WS connection to relay.celerp.com.
34
- # No value = no connection, no telemetry, no cloud dependency.
37
+ # No `[gateway_token]` means no gateway connection, no product telemetry, and
38
+ # no cloud dependency, except a startup subscription check.
35
39
  gateway_token: str = ""
36
40
  gateway_url: str = "wss://relay.celerp.com/ws/connect"
37
41
  # Unique instance identifier sent to gateway (auto-generated if blank).
@@ -46,10 +46,13 @@ async def check_and_run_daily_syncs(
46
46
  synced: list[str] = []
47
47
 
48
48
  async with get_session_ctx() as session:
49
+ # Reconcile EVERY enabled connector once a day — including realtime
50
+ # (webhook) ones — so a daily incremental pass backstops any webhooks
51
+ # missed while the instance/tunnel was offline (idempotency keys make
52
+ # webhook + reconcile converge to a single write).
49
53
  rows = await session.execute(
50
54
  sa.select(ConnectorConfig).where(
51
55
  ConnectorConfig.company_id == company_id,
52
- ConnectorConfig.sync_frequency == SyncFrequency.DAILY.value,
53
56
  )
54
57
  )
55
58
  configs = [row[0] for row in rows]
@@ -118,3 +121,24 @@ async def scheduler_loop(company_id: str, token_fetcher: TokenFetcher | None = N
118
121
  except Exception as exc:
119
122
  log.error("daily_scheduler: error: %s", exc)
120
123
  await asyncio.sleep(_CHECK_INTERVAL_SECONDS)
124
+
125
+
126
+ async def _distinct_company_ids() -> list[str]:
127
+ from celerp.db import get_session_ctx
128
+ async with get_session_ctx() as session:
129
+ rows = await session.execute(sa.select(ConnectorConfig.company_id).distinct())
130
+ return [r[0] for r in rows]
131
+
132
+
133
+ async def scheduler_loop_all(token_fetcher: TokenFetcher | None = None) -> None:
134
+ """Reconciliation backstop: hourly, run any due daily syncs for every company
135
+ that has a connector configured. Started from the API lifespan."""
136
+ while True:
137
+ try:
138
+ for company_id in await _distinct_company_ids():
139
+ synced = await check_and_run_daily_syncs(company_id, token_fetcher=token_fetcher)
140
+ if synced:
141
+ log.info("daily_scheduler: synced %s for %s", ", ".join(synced), company_id)
142
+ except Exception as exc:
143
+ log.error("daily_scheduler: loop error: %s", exc)
144
+ await asyncio.sleep(_CHECK_INTERVAL_SECONDS)
@@ -0,0 +1,50 @@
1
+ # Copyright (c) 2026 Noah Severs
2
+ # SPDX-License-Identifier: BUSL-1.1
3
+ """Fetch a short-lived connector access token from the relay.
4
+
5
+ Autonomous syncs (the reconciliation scheduler and webhook-triggered syncs) run
6
+ inside the core process, so unlike the manual sync route — where the UI passes
7
+ the token in the request body — they must fetch the token themselves. The relay
8
+ holds the encrypted token and returns a short-lived copy to the authenticated
9
+ instance. Returns None when there is no relay session (e.g. a self-hosted
10
+ instance not connected to Celerp Cloud), in which case the caller skips.
11
+ """
12
+ from __future__ import annotations
13
+
14
+ import logging
15
+ from typing import TYPE_CHECKING
16
+
17
+ log = logging.getLogger(__name__)
18
+
19
+ if TYPE_CHECKING:
20
+ from celerp.connectors.base import ConnectorContext
21
+
22
+
23
+ async def fetch_context(company_id: str, connector_name: str) -> "ConnectorContext | None":
24
+ import httpx
25
+
26
+ from celerp.connectors.base import ConnectorContext
27
+ from celerp.gateway.state import get_session_token, relay_http_url, relay_session_headers
28
+
29
+ if not get_session_token():
30
+ return None # no cloud session → no relay token available
31
+ try:
32
+ async with httpx.AsyncClient(timeout=15.0) as c:
33
+ r = await c.get(
34
+ f"{relay_http_url()}/tokens/{connector_name}/access-token",
35
+ headers=relay_session_headers(),
36
+ )
37
+ if r.status_code != 200:
38
+ log.debug("relay token fetch for %s returned %d", connector_name, r.status_code)
39
+ return None
40
+ data = r.json()
41
+ except Exception as exc:
42
+ log.warning("relay token fetch for %s failed: %s", connector_name, exc)
43
+ return None
44
+
45
+ return ConnectorContext(
46
+ company_id=company_id,
47
+ access_token=data["access_token"],
48
+ store_handle=data.get("store_handle"),
49
+ extra=data.get("extra"),
50
+ )
@@ -40,6 +40,17 @@ _API_VERSION = "2024-01"
40
40
  _PAGE_LIMIT = 250 # Shopify max per page
41
41
 
42
42
 
43
+ def _money(v) -> float | None:
44
+ """Parse a Shopify money value to float. Returns None only when genuinely
45
+ absent (missing/null/empty) — a real price of 0 stays 0.0, not None."""
46
+ if v is None or v == "":
47
+ return None
48
+ try:
49
+ return float(v)
50
+ except (TypeError, ValueError):
51
+ return None
52
+
53
+
43
54
  def _base_url(ctx: ConnectorContext) -> str:
44
55
  if not ctx.store_handle:
45
56
  raise ValueError("ConnectorContext.store_handle is required for Shopify")
@@ -126,7 +137,7 @@ class ShopifyConnector(ConnectorBase):
126
137
  sku=sku,
127
138
  name=name,
128
139
  sell_by="piece",
129
- sale_price=float(variant.get("price") or 0) or None,
140
+ sale_price=_money(variant.get("price")),
130
141
  quantity=float(variant.get("inventory_quantity") or 0),
131
142
  idempotency_key=idempotency_key,
132
143
  )
@@ -162,14 +173,19 @@ class ShopifyConnector(ConnectorBase):
162
173
 
163
174
  images: list[dict] = product.get("images", [])
164
175
 
176
+ from sqlalchemy import func
177
+
165
178
  async with get_async_session() as session:
166
- rows = (await session.execute(
179
+ # Resolve the item by SKU with a DB-side filter (case-insensitive),
180
+ # returning the single match — never load the whole catalog into
181
+ # memory per product (that was O(products × catalog_size)).
182
+ row = (await session.execute(
167
183
  select(Projection).where(
168
184
  Projection.company_id == ctx.company_id,
169
185
  Projection.entity_type == "item",
170
- )
171
- )).scalars().all()
172
- row = next((r for r in rows if str(r.state.get("sku", "")).strip().lower() == sku.strip().lower()), None)
186
+ func.lower(Projection.state["sku"].astext) == sku.strip().lower(),
187
+ ).limit(1)
188
+ )).scalar_one_or_none()
173
189
  if row is None:
174
190
  return
175
191
 
@@ -49,6 +49,12 @@ async def _check_period_lock(session, company_id, data: dict) -> None:
49
49
 
50
50
 
51
51
  async def emit_event(session, **kwargs) -> LedgerEntry:
52
+ # A backup represents a clean point in time: while one is building, pause writes
53
+ # (reads, which never emit, are unaffected) so nothing changes mid-backup.
54
+ from celerp.services.backup_state import is_active as _backup_active
55
+ if _backup_active():
56
+ raise HTTPException(status_code=503, detail="Backup in progress, try again shortly.")
57
+
52
58
  schema = EVENT_SCHEMA_MAP.get(kwargs["event_type"])
53
59
  if schema is None:
54
60
  raise ValueError(f"Unknown event_type: {kwargs['event_type']}")
@@ -240,6 +240,9 @@ class GatewayClient:
240
240
  elif msg_type == "http.request":
241
241
  asyncio.create_task(self._handle_proxy_request(payload))
242
242
 
243
+ elif msg_type == "shopify.webhook":
244
+ asyncio.create_task(self._handle_shopify_webhook(payload))
245
+
243
246
  else:
244
247
  log.debug("Unhandled gateway message type: %s", msg_type)
245
248
 
@@ -267,6 +270,38 @@ class GatewayClient:
267
270
  except Exception as exc:
268
271
  log.warning("Gateway: failed to persist feature_flags: %s", exc)
269
272
 
273
+ async def _handle_shopify_webhook(self, payload: dict) -> None:
274
+ """A Shopify webhook the relay forwarded. Trigger a targeted incremental
275
+ sync for the affected entity on each company with Shopify configured
276
+ (idempotency keys dedupe against the reconciliation pass)."""
277
+ topic = payload.get("topic", "")
278
+ data = payload.get("data") or {}
279
+ try:
280
+ import sqlalchemy as sa
281
+
282
+ from celerp.connectors.base import SyncDirection
283
+ from celerp.connectors.relay_token import fetch_context
284
+ from celerp.connectors.webhooks import WebhookEvent, handle_webhook
285
+ from celerp.db import get_session_ctx
286
+ from celerp.models.connector_config import ConnectorConfig
287
+
288
+ async with get_session_ctx() as session:
289
+ rows = await session.execute(
290
+ sa.select(ConnectorConfig.company_id, ConnectorConfig.direction).where(
291
+ ConnectorConfig.connector == "shopify"
292
+ )
293
+ )
294
+ configs = rows.all()
295
+
296
+ event = WebhookEvent(platform="shopify", topic=topic, payload=data)
297
+ for company_id, direction in configs:
298
+ ctx = await fetch_context(company_id, "shopify")
299
+ if ctx is None:
300
+ continue
301
+ await handle_webhook(event, ctx, direction=SyncDirection(direction))
302
+ except Exception as exc:
303
+ log.warning("shopify webhook handling failed (topic=%s): %s", topic, exc)
304
+
270
305
  async def _handle_proxy_request(self, payload: dict) -> None:
271
306
  """Handle a proxied HTTP request from the relay.
272
307
 
@@ -298,7 +333,7 @@ class GatewayClient:
298
333
  "payload": {
299
334
  "id": request_id,
300
335
  "status": 200,
301
- "headers": {"content-type": "text/event-stream", "cache-control": "no-cache"},
336
+ "headers": [["content-type", "text/event-stream"], ["cache-control", "no-cache"]],
302
337
  "body_b64": base64.b64encode(b"data: {}\n\n").decode(),
303
338
  },
304
339
  })
@@ -326,12 +361,16 @@ class GatewayClient:
326
361
  content=body,
327
362
  )
328
363
  resp_body_b64 = base64.b64encode(resp.content).decode() if resp.content else ""
329
- # Filter hop-by-hop headers from response
330
- _skip = {"transfer-encoding", "connection", "keep-alive"}
331
- resp_headers = {
332
- k: v for k, v in resp.headers.items()
364
+ # Serialize as an ORDERED LIST of pairs (not a dict): a response can carry several
365
+ # Set-Cookie headers (login/refresh emit access_token + refresh_token), and a dict would
366
+ # collapse them into one comma-joined value the browser can't parse — so the refresh
367
+ # cookie never reaches the browser and the session dies at the access token's hard cap.
368
+ # multi_items() keeps each header separate. Drop content-length; the relay recomputes it.
369
+ _skip = {"transfer-encoding", "connection", "keep-alive", "content-length"}
370
+ resp_headers = [
371
+ [k, v] for k, v in resp.headers.multi_items()
333
372
  if k.lower() not in _skip
334
- }
373
+ ]
335
374
  await self._send(self._ws, {
336
375
  "type": "http.response",
337
376
  "payload": {
@@ -348,7 +387,7 @@ class GatewayClient:
348
387
  "payload": {
349
388
  "id": request_id,
350
389
  "status": 502,
351
- "headers": {"content-type": "text/plain"},
390
+ "headers": [["content-type", "text/plain"]],
352
391
  "body_b64": base64.b64encode(
353
392
  f"Local app error: {type(exc).__name__}: {exc}".encode()
354
393
  ).decode(),
@@ -89,8 +89,9 @@ async def _try_auto_activate() -> None:
89
89
  _prev_level = _httpx_log.level
90
90
  _httpx_log.setLevel(logging.WARNING)
91
91
  try:
92
+ from celerp import __version__ as _ver
92
93
  async with httpx.AsyncClient(timeout=10.0) as c:
93
- r = await c.post(f"{relay_base}/auth/activate", json={"instance_id": iid})
94
+ r = await c.post(f"{relay_base}/auth/activate", json={"instance_id": iid, "version": _ver})
94
95
  finally:
95
96
  _httpx_log.setLevel(_prev_level)
96
97
  if r.status_code != 200:
@@ -199,6 +200,22 @@ async def lifespan(_app: FastAPI):
199
200
  "_module": "_kernel",
200
201
  })
201
202
 
203
+ # Develop→release guard: on a version change, rebuild projections with the
204
+ # release's handlers (now that all handlers are registered). Gated by a
205
+ # marker so it runs once per version. Non-fatal: a failure must not block
206
+ # boot — the marker stays unset and a later boot retries.
207
+ try:
208
+ from celerp.db import SessionLocal as _GuardSession
209
+ from celerp.services.dev_release_guard import run_upgrade_guard
210
+ async with _GuardSession() as _guard_sess:
211
+ await run_upgrade_guard(_guard_sess)
212
+ await _guard_sess.commit()
213
+ except Exception:
214
+ logging.getLogger(__name__).exception(
215
+ "Develop→release upgrade guard failed (non-fatal); projections may be "
216
+ "stale until rebuilt via doctor or /ledger/rebuild"
217
+ )
218
+
202
219
  # Start gateway client if configured (opt-in, no-op if GATEWAY_TOKEN is blank)
203
220
  gateway_task = None
204
221
  if settings.gateway_token:
@@ -230,6 +247,13 @@ async def lifespan(_app: FastAPI):
230
247
  from celerp.services.session_tracker import run_jti_cleanup_loop
231
248
  jti_cleanup_task = asyncio.create_task(run_jti_cleanup_loop())
232
249
 
250
+ # Connector reconciliation scheduler: a daily incremental sync per connector,
251
+ # backstopping any realtime webhooks missed while offline. No-op without a
252
+ # relay session (self-hosted instances skip token fetch).
253
+ from celerp.connectors.daily_scheduler import scheduler_loop_all
254
+ from celerp.connectors.relay_token import fetch_context as _connector_token_fetcher
255
+ connector_sched_task = asyncio.create_task(scheduler_loop_all(token_fetcher=_connector_token_fetcher))
256
+
233
257
  yield
234
258
 
235
259
  # Terminate all active SSE connections so Uvicorn doesn't hang on shutdown
@@ -239,6 +263,7 @@ async def lifespan(_app: FastAPI):
239
263
  # Stop background tasks
240
264
  cleanup_task.cancel()
241
265
  jti_cleanup_task.cancel()
266
+ connector_sched_task.cancel()
242
267
  try:
243
268
  await cleanup_task
244
269
  except asyncio.CancelledError:
@@ -73,10 +73,13 @@ class MaxBodySizeMiddleware:
73
73
  await self.app(scope, receive, send)
74
74
  return
75
75
 
76
- # Bulk file/cert import legitimately uploads a large ZIP (many small files);
77
- # exempt it from the body cap. It's bounded instead by the WS tunnel frame
78
- # size and the per-file 50 MB limit in store_upload().
79
- if scope.get("path", "").endswith(("/items/files/bulk", "/items/attachments/bulk")):
76
+ # Bulk file/cert import and backup restore legitimately upload large archives;
77
+ # exempt them from the body cap. Bulk imports are bounded by the WS tunnel frame
78
+ # size and the per-file 50 MB limit in store_upload(); a .celerp-backup restore is
79
+ # a trusted whole-instance archive (DB + files) that is inherently large.
80
+ if scope.get("path", "").endswith(
81
+ ("/items/files/bulk", "/items/attachments/bulk", "/backup/import", "/backup/import-bootstrap")
82
+ ):
80
83
  await self.app(scope, receive, send)
81
84
  return
82
85