monkeybrain-runtime 1.0.0__py3-none-any.whl

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 (838) hide show
  1. monkeybrain_runtime-1.0.0.dist-info/METADATA +76 -0
  2. monkeybrain_runtime-1.0.0.dist-info/RECORD +838 -0
  3. monkeybrain_runtime-1.0.0.dist-info/WHEEL +5 -0
  4. monkeybrain_runtime-1.0.0.dist-info/entry_points.txt +3 -0
  5. monkeybrain_runtime-1.0.0.dist-info/top_level.txt +2 -0
  6. services/__init__.py +8 -0
  7. services/agentos/__init__.py +0 -0
  8. services/agentos/main.py +1 -0
  9. services/assets/helpers/__init__.py +12 -0
  10. services/assets/helpers/device.py +59 -0
  11. services/assets/helpers/equipment.py +179 -0
  12. services/assets/helpers/instruments.py +72 -0
  13. services/assets/helpers/machines.py +183 -0
  14. services/assets/helpers/materials.py +76 -0
  15. services/assets/helpers/parts.py +116 -0
  16. services/assets/helpers/plc.py +134 -0
  17. services/assets/helpers/tags.py +108 -0
  18. services/assets/helpers/tools.py +101 -0
  19. services/assets/main.py +75 -0
  20. services/assets/models/__init__.py +12 -0
  21. services/assets/models/device.py +79 -0
  22. services/assets/models/equipment.py +222 -0
  23. services/assets/models/instruments.py +85 -0
  24. services/assets/models/machines.py +230 -0
  25. services/assets/models/material.py +266 -0
  26. services/assets/models/parts.py +96 -0
  27. services/assets/models/plc.py +264 -0
  28. services/assets/models/tags.py +76 -0
  29. services/assets/models/tools.py +179 -0
  30. services/assets/routers/__init__.py +12 -0
  31. services/assets/routers/classes.py +65 -0
  32. services/assets/routers/device.py +86 -0
  33. services/assets/routers/equipment.py +145 -0
  34. services/assets/routers/families.py +61 -0
  35. services/assets/routers/instruments.py +70 -0
  36. services/assets/routers/machines.py +136 -0
  37. services/assets/routers/materials.py +105 -0
  38. services/assets/routers/parts.py +130 -0
  39. services/assets/routers/plc.py +94 -0
  40. services/assets/routers/subclasses.py +68 -0
  41. services/assets/routers/tags.py +138 -0
  42. services/assets/routers/tools.py +113 -0
  43. services/auth/helpers/__init__.py +13 -0
  44. services/auth/helpers/approval_decisions.py +261 -0
  45. services/auth/helpers/audit_elasticsearch_sync.py +350 -0
  46. services/auth/helpers/departments.py +53 -0
  47. services/auth/helpers/graph_store.py +848 -0
  48. services/auth/helpers/influx_store.py +280 -0
  49. services/auth/helpers/me.py +33 -0
  50. services/auth/helpers/nats_consumer.py +618 -0
  51. services/auth/helpers/nats_store.py +242 -0
  52. services/auth/helpers/permissions.py +62 -0
  53. services/auth/helpers/roles.py +87 -0
  54. services/auth/helpers/store.py +54 -0
  55. services/auth/helpers/team_members.py +155 -0
  56. services/auth/helpers/teams.py +87 -0
  57. services/auth/helpers/tokens.py +71 -0
  58. services/auth/helpers/users.py +119 -0
  59. services/auth/helpers/websocket_broadcast.py +41 -0
  60. services/auth/main.py +88 -0
  61. services/auth/models/__init__.py +12 -0
  62. services/auth/models/departments.py +55 -0
  63. services/auth/models/login.py +20 -0
  64. services/auth/models/permissions.py +61 -0
  65. services/auth/models/roles.py +53 -0
  66. services/auth/models/session.py +26 -0
  67. services/auth/models/teamMembers.py +59 -0
  68. services/auth/models/teams.py +56 -0
  69. services/auth/models/users.py +77 -0
  70. services/auth/routers/__init__.py +14 -0
  71. services/auth/routers/auth.py +3839 -0
  72. services/auth/routers/departments.py +84 -0
  73. services/auth/routers/integration_config.py +703 -0
  74. services/auth/routers/me.py +28 -0
  75. services/auth/routers/permissions.py +96 -0
  76. services/auth/routers/roles.py +139 -0
  77. services/auth/routers/session.py +224 -0
  78. services/auth/routers/team_members.py +152 -0
  79. services/auth/routers/teams.py +112 -0
  80. services/auth/routers/users.py +131 -0
  81. services/auth/routers/websocket_events.py +247 -0
  82. services/batch_execution/__init__.py +19 -0
  83. services/batch_execution/pipeline_triggers/__init__.py +53 -0
  84. services/batch_execution/pipeline_triggers/pipeline_parameter_adjuster.py +440 -0
  85. services/batch_execution/pipeline_triggers/pipeline_trigger_engine.py +445 -0
  86. services/batch_execution/pipeline_triggers/re_evaluation_queue.py +341 -0
  87. services/batch_execution/pipeline_triggers/test_phase3_implementation.py +553 -0
  88. services/batch_execution/pipeline_triggers/workflow_reevaluator.py +367 -0
  89. services/batch_execution/smoke_test_e2e_feedback_loop.py +704 -0
  90. services/batch_execution/workflow_executor.py +478 -0
  91. services/changeover/helpers/__init__.py +11 -0
  92. services/changeover/helpers/changeover.py +87 -0
  93. services/changeover/helpers/changeover_common.py +55 -0
  94. services/changeover/helpers/changeover_events.py +66 -0
  95. services/changeover/helpers/changeover_kpis.py +33 -0
  96. services/changeover/helpers/changeover_matrix.py +60 -0
  97. services/changeover/helpers/changeover_procedures.py +164 -0
  98. services/changeover/helpers/changeover_windows.py +96 -0
  99. services/changeover/main.py +52 -0
  100. services/changeover/models/__init__.py +11 -0
  101. services/changeover/models/changeover.py +73 -0
  102. services/changeover/models/changeover_events.py +142 -0
  103. services/changeover/models/changeover_kpis.py +75 -0
  104. services/changeover/models/changeover_matrix.py +63 -0
  105. services/changeover/models/changeover_procedures.py +108 -0
  106. services/changeover/models/changeover_tasks.py +87 -0
  107. services/changeover/models/changeover_windows.py +72 -0
  108. services/changeover/routers/__init__.py +9 -0
  109. services/changeover/routers/changeover_events.py +127 -0
  110. services/changeover/routers/changeover_kpis.py +80 -0
  111. services/changeover/routers/changeover_matrix.py +80 -0
  112. services/changeover/routers/changeover_procedures.py +118 -0
  113. services/changeover/routers/changeover_windows.py +98 -0
  114. services/common/__init__.py +2 -0
  115. services/common/approval_chains.py +648 -0
  116. services/common/auth.py +56 -0
  117. services/common/cdc.py +52 -0
  118. services/common/compat.py +217 -0
  119. services/common/compliance.py +562 -0
  120. services/common/config.py +134 -0
  121. services/common/cors.py +17 -0
  122. services/common/data_transformation.py +195 -0
  123. services/common/db.py +577 -0
  124. services/common/embeddings.py +97 -0
  125. services/common/event_reducers.py +194 -0
  126. services/common/event_types.py +51 -0
  127. services/common/integration_ingestion.py +169 -0
  128. services/common/logging.py +204 -0
  129. services/common/models/__init__.py +2 -0
  130. services/common/models/databricks.py +25 -0
  131. services/common/models/enums.py +64 -0
  132. services/common/module_control.py +422 -0
  133. services/common/mongo_cdc_watcher.py +106 -0
  134. services/common/n8n_auth.py +22 -0
  135. services/common/neo4j_mirror.py +1087 -0
  136. services/common/ontology_registry.py +110 -0
  137. services/common/reasoning_traces.py +52 -0
  138. services/common/supply_chain_cdc.py +555 -0
  139. services/common/tracing.py +159 -0
  140. services/common/utils.py +30 -0
  141. services/customers/helpers/__init__.py +8 -0
  142. services/customers/helpers/customer_details.py +64 -0
  143. services/customers/helpers/customer_metadata.py +64 -0
  144. services/customers/helpers/customer_order_metrics.py +67 -0
  145. services/customers/helpers/customer_payment_data.py +67 -0
  146. services/customers/main.py +50 -0
  147. services/customers/models/__init__.py +8 -0
  148. services/customers/models/customer_details.py +42 -0
  149. services/customers/models/customer_metadata.py +97 -0
  150. services/customers/models/customer_order_metrics.py +86 -0
  151. services/customers/models/customer_payment_data.py +60 -0
  152. services/customers/routers/__init__.py +8 -0
  153. services/customers/routers/customer_details.py +88 -0
  154. services/customers/routers/customer_metadata.py +88 -0
  155. services/customers/routers/customer_order_metrics.py +88 -0
  156. services/customers/routers/customer_payment_data.py +88 -0
  157. services/documents/__init__.py +1 -0
  158. services/documents/helpers/__init__.py +6 -0
  159. services/documents/helpers/document_metadata.py +569 -0
  160. services/documents/helpers/document_workflows.py +215 -0
  161. services/documents/helpers/report_templates.py +113 -0
  162. services/documents/main.py +49 -0
  163. services/documents/models/__init__.py +6 -0
  164. services/documents/models/document_metadata.py +215 -0
  165. services/documents/models/document_workflows.py +136 -0
  166. services/documents/models/report_templates.py +132 -0
  167. services/documents/routers/__init__.py +6 -0
  168. services/documents/routers/document_metadata.py +654 -0
  169. services/documents/routers/document_workflows.py +146 -0
  170. services/documents/routers/report_templates.py +86 -0
  171. services/events/helpers/__init__.py +5 -0
  172. services/events/helpers/events.py +394 -0
  173. services/events/main.py +40 -0
  174. services/events/models/__init__.py +5 -0
  175. services/events/models/events.py +50 -0
  176. services/events/routers/__init__.py +6 -0
  177. services/events/routers/count_events.py +109 -0
  178. services/events/routers/events.py +75 -0
  179. services/events/seed_events.py +196 -0
  180. services/facilities/helpers/__init__.py +8 -0
  181. services/facilities/helpers/lines.py +74 -0
  182. services/facilities/helpers/locations.py +231 -0
  183. services/facilities/helpers/plants.py +59 -0
  184. services/facilities/helpers/stages.py +110 -0
  185. services/facilities/helpers/workstation.py +213 -0
  186. services/facilities/main.py +60 -0
  187. services/facilities/models/__init__.py +10 -0
  188. services/facilities/models/industrialLine.py +72 -0
  189. services/facilities/models/industrialPlant.py +164 -0
  190. services/facilities/models/locations.py +74 -0
  191. services/facilities/models/stages.py +92 -0
  192. services/facilities/models/worker.py +73 -0
  193. services/facilities/models/workstation.py +117 -0
  194. services/facilities/models/workstation_live_state.py +59 -0
  195. services/facilities/routers/__init__.py +8 -0
  196. services/facilities/routers/bays.py +81 -0
  197. services/facilities/routers/buildings.py +92 -0
  198. services/facilities/routers/floors.py +81 -0
  199. services/facilities/routers/lines.py +154 -0
  200. services/facilities/routers/locations.py +208 -0
  201. services/facilities/routers/plant.py +203 -0
  202. services/facilities/routers/rooms.py +81 -0
  203. services/facilities/routers/stages.py +152 -0
  204. services/facilities/routers/workstation.py +173 -0
  205. services/file/backup.py +71 -0
  206. services/file/main.py +45 -0
  207. services/file/recieve.py +54 -0
  208. services/file/send.py +55 -0
  209. services/file/src/core/config.py +90 -0
  210. services/file/src/core/keycloak.py +152 -0
  211. services/file/src/core/logging_config.py +9 -0
  212. services/file/src/core/security.py +33 -0
  213. services/file/src/helpers/cad_conversion.py +331 -0
  214. services/file/src/helpers/helpers.py +825 -0
  215. services/file/src/routes/cad_conversion.py +26 -0
  216. services/file/src/routes/files.py +136 -0
  217. services/file/src/routes/presigned.py +154 -0
  218. services/file/src/services/websocket.py +293 -0
  219. services/floor_layout/helpers/__init__.py +8 -0
  220. services/floor_layout/helpers/bays.py +92 -0
  221. services/floor_layout/helpers/buildings.py +54 -0
  222. services/floor_layout/helpers/floors.py +65 -0
  223. services/floor_layout/helpers/rooms.py +76 -0
  224. services/floor_layout/main.py +52 -0
  225. services/floor_layout/models/__init__.py +8 -0
  226. services/floor_layout/models/bays.py +65 -0
  227. services/floor_layout/models/buildings.py +52 -0
  228. services/floor_layout/models/floors.py +45 -0
  229. services/floor_layout/models/rooms.py +61 -0
  230. services/floor_layout/routers/__init__.py +9 -0
  231. services/floor_layout/routers/bays.py +143 -0
  232. services/floor_layout/routers/buildings.py +116 -0
  233. services/floor_layout/routers/floors.py +89 -0
  234. services/floor_layout/routers/locations.py +80 -0
  235. services/floor_layout/routers/rooms.py +134 -0
  236. services/inventory/helpers/__init__.py +13 -0
  237. services/inventory/helpers/cycle_counts.py +124 -0
  238. services/inventory/helpers/inventory_allocations.py +134 -0
  239. services/inventory/helpers/inventory_item_counts.py +114 -0
  240. services/inventory/helpers/inventory_item_quantities.py +114 -0
  241. services/inventory/helpers/inventory_items.py +103 -0
  242. services/inventory/helpers/inventory_stage_outputs.py +134 -0
  243. services/inventory/helpers/inventory_transactions.py +112 -0
  244. services/inventory/helpers/stock_adjustment_requests.py +101 -0
  245. services/inventory/helpers/warehouse_cycle_counts.py +133 -0
  246. services/inventory/helpers/warehouse_locations.py +213 -0
  247. services/inventory/helpers/warehouse_regulated_records.py +123 -0
  248. services/inventory/main.py +62 -0
  249. services/inventory/models/__init__.py +17 -0
  250. services/inventory/models/cycle_counts.py +99 -0
  251. services/inventory/models/inventory_allocations.py +121 -0
  252. services/inventory/models/inventory_common.py +65 -0
  253. services/inventory/models/inventory_enums.py +21 -0
  254. services/inventory/models/inventory_item_count.py +65 -0
  255. services/inventory/models/inventory_item_quantity.py +82 -0
  256. services/inventory/models/inventory_items.py +168 -0
  257. services/inventory/models/inventory_responses.py +44 -0
  258. services/inventory/models/inventory_stage_outputs.py +96 -0
  259. services/inventory/models/inventory_state.py +15 -0
  260. services/inventory/models/inventory_transactions.py +80 -0
  261. services/inventory/models/stock_adjustment_requests.py +109 -0
  262. services/inventory/models/warehouse_cycle_counts.py +119 -0
  263. services/inventory/models/warehouse_location_models.py +708 -0
  264. services/inventory/models/warehouse_regulated_records.py +358 -0
  265. services/inventory/routers/__init__.py +13 -0
  266. services/inventory/routers/cycle_counts.py +106 -0
  267. services/inventory/routers/inventory_allocations.py +125 -0
  268. services/inventory/routers/inventory_item_counts.py +105 -0
  269. services/inventory/routers/inventory_item_quantities.py +105 -0
  270. services/inventory/routers/inventory_items.py +109 -0
  271. services/inventory/routers/inventory_stage_outputs.py +122 -0
  272. services/inventory/routers/inventory_transactions.py +96 -0
  273. services/inventory/routers/stock_adjustment_requests.py +124 -0
  274. services/inventory/routers/warehouse_cycle_counts.py +124 -0
  275. services/inventory/routers/warehouse_locations.py +426 -0
  276. services/inventory/routers/warehouse_regulated_records.py +273 -0
  277. services/iot/helpers/__init__.py +8 -0
  278. services/iot/helpers/ble_device.py +87 -0
  279. services/iot/helpers/mqtt_bridge.py +115 -0
  280. services/iot/helpers/sensor_readings.py +63 -0
  281. services/iot/helpers/sensors.py +77 -0
  282. services/iot/helpers/servers.py +72 -0
  283. services/iot/helpers/uwb_device.py +95 -0
  284. services/iot/main.py +53 -0
  285. services/iot/models/__init__.py +8 -0
  286. services/iot/models/ble_device.py +118 -0
  287. services/iot/models/sensors.py +256 -0
  288. services/iot/models/servers.py +206 -0
  289. services/iot/models/uwb_device.py +106 -0
  290. services/iot/routers/__init__.py +8 -0
  291. services/iot/routers/ble_device.py +110 -0
  292. services/iot/routers/sensors.py +144 -0
  293. services/iot/routers/servers.py +141 -0
  294. services/iot/routers/uwb_device.py +148 -0
  295. services/module_control/__init__.py +1 -0
  296. services/module_control/helpers/__init__.py +1 -0
  297. services/module_control/helpers/integration_config.py +243 -0
  298. services/module_control/helpers/security.py +104 -0
  299. services/module_control/main.py +44 -0
  300. services/module_control/models/__init__.py +1 -0
  301. services/module_control/models/module_control.py +65 -0
  302. services/module_control/routers/__init__.py +1 -0
  303. services/module_control/routers/module_control.py +219 -0
  304. services/orders/helpers/__init__.py +11 -0
  305. services/orders/helpers/invoices.py +123 -0
  306. services/orders/helpers/order_customer_metrics.py +61 -0
  307. services/orders/helpers/order_details.py +71 -0
  308. services/orders/helpers/order_metadata.py +61 -0
  309. services/orders/helpers/order_payment_metadata.py +74 -0
  310. services/orders/helpers/orders.py +119 -0
  311. services/orders/helpers/sales_orders.py +136 -0
  312. services/orders/main.py +56 -0
  313. services/orders/models/__init__.py +11 -0
  314. services/orders/models/invoices.py +415 -0
  315. services/orders/models/order_customer_metrics.py +78 -0
  316. services/orders/models/order_details.py +46 -0
  317. services/orders/models/order_metadata.py +60 -0
  318. services/orders/models/order_payment_metadata.py +63 -0
  319. services/orders/models/orders.py +64 -0
  320. services/orders/models/sales_orders.py +130 -0
  321. services/orders/routers/__init__.py +11 -0
  322. services/orders/routers/invoices.py +111 -0
  323. services/orders/routers/order_customer_metrics.py +87 -0
  324. services/orders/routers/order_details.py +87 -0
  325. services/orders/routers/order_metadata.py +87 -0
  326. services/orders/routers/order_payment_metadata.py +87 -0
  327. services/orders/routers/orders.py +74 -0
  328. services/orders/routers/sales_orders.py +111 -0
  329. services/pm/helpers/__init__.py +14 -0
  330. services/pm/helpers/calendar_bookings.py +114 -0
  331. services/pm/helpers/calibration_point.py +110 -0
  332. services/pm/helpers/calibrations.py +196 -0
  333. services/pm/helpers/checklists.py +318 -0
  334. services/pm/helpers/cleaning.py +333 -0
  335. services/pm/helpers/downtime.py +376 -0
  336. services/pm/helpers/kanban_boards.py +186 -0
  337. services/pm/helpers/maintainance.py +177 -0
  338. services/pm/helpers/sop.py +1155 -0
  339. services/pm/helpers/sop_cdc.py +324 -0
  340. services/pm/helpers/weekly_schedules.py +79 -0
  341. services/pm/main.py +62 -0
  342. services/pm/models/__init__.py +14 -0
  343. services/pm/models/calendar_booking.py +82 -0
  344. services/pm/models/calibration_point.py +44 -0
  345. services/pm/models/calibrations.py +167 -0
  346. services/pm/models/checklists.py +117 -0
  347. services/pm/models/cleaning.py +203 -0
  348. services/pm/models/downtime.py +109 -0
  349. services/pm/models/kanban_board.py +178 -0
  350. services/pm/models/maintainanceLog.py +148 -0
  351. services/pm/models/sop.py +152 -0
  352. services/pm/models/weekly_schedule.py +91 -0
  353. services/pm/routers/__init__.py +14 -0
  354. services/pm/routers/calendar_bookings.py +143 -0
  355. services/pm/routers/calibration_point.py +94 -0
  356. services/pm/routers/calibrations.py +232 -0
  357. services/pm/routers/checklists.py +188 -0
  358. services/pm/routers/cleaning.py +127 -0
  359. services/pm/routers/downtime.py +143 -0
  360. services/pm/routers/kanban_boards.py +283 -0
  361. services/pm/routers/maintainance.py +241 -0
  362. services/pm/routers/sop.py +437 -0
  363. services/pm/routers/weekly_schedules.py +108 -0
  364. services/process_definitions/helpers/__init__.py +11 -0
  365. services/process_definitions/helpers/cpp_cqa_registry.py +120 -0
  366. services/process_definitions/helpers/mbmr_templates.py +107 -0
  367. services/process_definitions/helpers/packing_instructions.py +113 -0
  368. services/process_definitions/helpers/process_constraints.py +495 -0
  369. services/process_definitions/helpers/process_corrections.py +279 -0
  370. services/process_definitions/helpers/process_definition.py +996 -0
  371. services/process_definitions/helpers/process_node_catalog.py +786 -0
  372. services/process_definitions/helpers/process_post_checks.py +441 -0
  373. services/process_definitions/helpers/process_pre_checks.py +351 -0
  374. services/process_definitions/helpers/process_steps.py +220 -0
  375. services/process_definitions/main.py +71 -0
  376. services/process_definitions/models/__init__.py +13 -0
  377. services/process_definitions/models/cpp_cqa_registry.py +145 -0
  378. services/process_definitions/models/gxp_change_controls.py +38 -0
  379. services/process_definitions/models/gxp_risk_assessments.py +30 -0
  380. services/process_definitions/models/gxp_validation_evidence.py +33 -0
  381. services/process_definitions/models/mbmr_templates.py +173 -0
  382. services/process_definitions/models/packing_instructions.py +176 -0
  383. services/process_definitions/models/process_constraints.py +159 -0
  384. services/process_definitions/models/process_corrections.py +118 -0
  385. services/process_definitions/models/process_definition.py +685 -0
  386. services/process_definitions/models/process_definition_common.py +48 -0
  387. services/process_definitions/models/process_node_catalog.py +25 -0
  388. services/process_definitions/models/process_post_checks.py +171 -0
  389. services/process_definitions/models/process_pre_checks.py +168 -0
  390. services/process_definitions/models/process_steps.py +170 -0
  391. services/process_definitions/node_services/__init__.py +8 -0
  392. services/process_definitions/node_services/common.py +95 -0
  393. services/process_definitions/node_services/executor.py +499 -0
  394. services/process_definitions/node_services/flow_simulator.py +733 -0
  395. services/process_definitions/node_services/functions.py +193 -0
  396. services/process_definitions/node_services/messaging.py +44 -0
  397. services/process_definitions/node_services/models.py +221 -0
  398. services/process_definitions/node_services/network.py +161 -0
  399. services/process_definitions/node_services/parsers.py +87 -0
  400. services/process_definitions/node_services/sequence.py +95 -0
  401. services/process_definitions/node_services/storage.py +50 -0
  402. services/process_definitions/node_services/webhooks.py +52 -0
  403. services/process_definitions/routers/__init__.py +10 -0
  404. services/process_definitions/routers/cpp_cqa_registry.py +86 -0
  405. services/process_definitions/routers/mbmr_templates.py +84 -0
  406. services/process_definitions/routers/packing_instructions.py +84 -0
  407. services/process_definitions/routers/process_constraints.py +564 -0
  408. services/process_definitions/routers/process_corrections.py +343 -0
  409. services/process_definitions/routers/process_definition.py +992 -0
  410. services/process_definitions/routers/process_post_checks.py +529 -0
  411. services/process_definitions/routers/process_pre_checks.py +435 -0
  412. services/process_definitions/routers/process_steps.py +274 -0
  413. services/procurement/helpers/__init__.py +9 -0
  414. services/procurement/helpers/goods_receipts.py +240 -0
  415. services/procurement/helpers/purchase_order_shipping_information.py +85 -0
  416. services/procurement/helpers/purchase_orders.py +68 -0
  417. services/procurement/helpers/quality_control.py +235 -0
  418. services/procurement/helpers/sampling.py +404 -0
  419. services/procurement/main.py +52 -0
  420. services/procurement/models/__init__.py +9 -0
  421. services/procurement/models/goods_receipts.py +165 -0
  422. services/procurement/models/purchase_orders.py +54 -0
  423. services/procurement/models/quality_control.py +464 -0
  424. services/procurement/models/reinspection_records.py +28 -0
  425. services/procurement/models/sampling.py +262 -0
  426. services/procurement/models/shipping_information.py +51 -0
  427. services/procurement/routers/__init__.py +9 -0
  428. services/procurement/routers/goods_receipts.py +201 -0
  429. services/procurement/routers/purchase_orders.py +106 -0
  430. services/procurement/routers/quality_control.py +386 -0
  431. services/procurement/routers/sampling.py +296 -0
  432. services/procurement/routers/shipping_information.py +97 -0
  433. services/production/__init__.py +1 -0
  434. services/production/agents/__init__.py +5 -0
  435. services/production/agents/batch_planning_agent.py +815 -0
  436. services/production/models/__init__.py +25 -0
  437. services/production/models/batch.py +253 -0
  438. services/products/helpers/__init__.py +10 -0
  439. services/products/helpers/boms.py +100 -0
  440. services/products/helpers/drug_research.py +644 -0
  441. services/products/helpers/product_component.py +168 -0
  442. services/products/helpers/product_inventory.py +221 -0
  443. services/products/helpers/product_pricing.py +123 -0
  444. services/products/helpers/product_utils.py +32 -0
  445. services/products/helpers/products.py +81 -0
  446. services/products/main.py +59 -0
  447. services/products/models/__init__.py +9 -0
  448. services/products/models/drug_research.py +138 -0
  449. services/products/models/product_common.py +60 -0
  450. services/products/models/product_component.py +1028 -0
  451. services/products/models/product_inventory.py +118 -0
  452. services/products/models/product_pricing.py +73 -0
  453. services/products/models/products.py +151 -0
  454. services/products/routers/__init__.py +9 -0
  455. services/products/routers/boms.py +116 -0
  456. services/products/routers/drug_research.py +115 -0
  457. services/products/routers/product_components.py +123 -0
  458. services/products/routers/product_inventory.py +185 -0
  459. services/products/routers/product_pricing.py +136 -0
  460. services/products/routers/products.py +165 -0
  461. services/replenishment/__init__.py +1 -0
  462. services/replenishment/main.py +46 -0
  463. services/replenishment/routers/__init__.py +1 -0
  464. services/replenishment/routers/replenishment.py +20 -0
  465. services/shifts/helpers/__init__.py +7 -0
  466. services/shifts/helpers/shift_templates.py +124 -0
  467. services/shifts/helpers/shifts.py +79 -0
  468. services/shifts/helpers/timesheets.py +137 -0
  469. services/shifts/main.py +48 -0
  470. services/shifts/models/__init__.py +8 -0
  471. services/shifts/models/shift.py +62 -0
  472. services/shifts/models/shift_template.py +82 -0
  473. services/shifts/models/time_range.py +31 -0
  474. services/shifts/models/timesheet.py +196 -0
  475. services/shifts/routers/__init__.py +7 -0
  476. services/shifts/routers/shift_templates.py +97 -0
  477. services/shifts/routers/shifts.py +117 -0
  478. services/shifts/routers/timesheets.py +117 -0
  479. services/shipping/helpers/__init__.py +15 -0
  480. services/shipping/helpers/carrier.py +78 -0
  481. services/shipping/helpers/customs_declaration.py +104 -0
  482. services/shipping/helpers/delivery_note.py +99 -0
  483. services/shipping/helpers/package.py +95 -0
  484. services/shipping/helpers/pallet.py +85 -0
  485. services/shipping/helpers/route.py +93 -0
  486. services/shipping/helpers/shipping_information.py +82 -0
  487. services/shipping/helpers/shipping_provider_details.py +59 -0
  488. services/shipping/helpers/shipping_provider_metadata.py +59 -0
  489. services/shipping/helpers/vehicle.py +85 -0
  490. services/shipping/helpers/waybill.py +86 -0
  491. services/shipping/main.py +64 -0
  492. services/shipping/models/__init__.py +15 -0
  493. services/shipping/models/carrier.py +97 -0
  494. services/shipping/models/customs_declaration.py +138 -0
  495. services/shipping/models/delivery_note.py +163 -0
  496. services/shipping/models/package.py +152 -0
  497. services/shipping/models/pallet.py +137 -0
  498. services/shipping/models/route.py +120 -0
  499. services/shipping/models/shipping_information.py +55 -0
  500. services/shipping/models/shipping_provider_details.py +42 -0
  501. services/shipping/models/shipping_provider_metadata.py +54 -0
  502. services/shipping/models/vehicle.py +129 -0
  503. services/shipping/models/waybill.py +189 -0
  504. services/shipping/routers/__init__.py +15 -0
  505. services/shipping/routers/carrier.py +99 -0
  506. services/shipping/routers/customs_declaration.py +132 -0
  507. services/shipping/routers/delivery_note.py +150 -0
  508. services/shipping/routers/package.py +141 -0
  509. services/shipping/routers/pallet.py +108 -0
  510. services/shipping/routers/route.py +128 -0
  511. services/shipping/routers/shipping_information.py +97 -0
  512. services/shipping/routers/shipping_provider_details.py +80 -0
  513. services/shipping/routers/shipping_provider_metadata.py +80 -0
  514. services/shipping/routers/vehicle.py +117 -0
  515. services/shipping/routers/waybill.py +119 -0
  516. services/suppliers/helpers/__init__.py +13 -0
  517. services/suppliers/helpers/supplier_capabilities.py +58 -0
  518. services/suppliers/helpers/supplier_certifications.py +67 -0
  519. services/suppliers/helpers/supplier_details.py +58 -0
  520. services/suppliers/helpers/supplier_financials.py +58 -0
  521. services/suppliers/helpers/supplier_inventory.py +74 -0
  522. services/suppliers/helpers/supplier_locations.py +60 -0
  523. services/suppliers/helpers/supplier_pricing.py +69 -0
  524. services/suppliers/helpers/supplier_quality.py +69 -0
  525. services/suppliers/helpers/supplier_shipping.py +69 -0
  526. services/suppliers/main.py +60 -0
  527. services/suppliers/models/__init__.py +13 -0
  528. services/suppliers/models/supplier_capabilities.py +70 -0
  529. services/suppliers/models/supplier_certifications.py +64 -0
  530. services/suppliers/models/supplier_details.py +75 -0
  531. services/suppliers/models/supplier_financials.py +69 -0
  532. services/suppliers/models/supplier_inventory.py +76 -0
  533. services/suppliers/models/supplier_locations.py +70 -0
  534. services/suppliers/models/supplier_pricing.py +74 -0
  535. services/suppliers/models/supplier_quality.py +74 -0
  536. services/suppliers/models/supplier_shipping.py +76 -0
  537. services/suppliers/routers/__init__.py +13 -0
  538. services/suppliers/routers/supplier_capabilities.py +88 -0
  539. services/suppliers/routers/supplier_certifications.py +87 -0
  540. services/suppliers/routers/supplier_details.py +83 -0
  541. services/suppliers/routers/supplier_financials.py +83 -0
  542. services/suppliers/routers/supplier_inventory.py +105 -0
  543. services/suppliers/routers/supplier_locations.py +89 -0
  544. services/suppliers/routers/supplier_pricing.py +96 -0
  545. services/suppliers/routers/supplier_quality.py +96 -0
  546. services/suppliers/routers/supplier_shipping.py +96 -0
  547. services/supply_allocation/main.py +46 -0
  548. services/supply_allocation/routers/__init__.py +1 -0
  549. services/supply_allocation/routers/allocation.py +20 -0
  550. services/taxonomy/helpers/__init__.py +7 -0
  551. services/taxonomy/helpers/classes.py +48 -0
  552. services/taxonomy/helpers/family.py +53 -0
  553. services/taxonomy/helpers/subclass.py +58 -0
  554. services/taxonomy/main.py +48 -0
  555. services/taxonomy/models/__init__.py +7 -0
  556. services/taxonomy/models/classes.py +52 -0
  557. services/taxonomy/models/family.py +60 -0
  558. services/taxonomy/models/subclass.py +50 -0
  559. services/taxonomy/routers/__init__.py +7 -0
  560. services/taxonomy/routers/classes.py +78 -0
  561. services/taxonomy/routers/family.py +77 -0
  562. services/taxonomy/routers/subclass.py +82 -0
  563. services/warehouse_execution/__init__.py +1 -0
  564. services/warehouse_execution/main.py +46 -0
  565. services/warehouse_execution/routers/__init__.py +1 -0
  566. services/warehouse_execution/routers/execution.py +21 -0
  567. services/work_order_agent/__init__.py +17 -0
  568. services/work_order_agent/agent/__init__.py +17 -0
  569. services/work_order_agent/agent/work_order_agent.py +658 -0
  570. services/work_order_agent/tracking/__init__.py +101 -0
  571. services/work_order_agent/tracking/event_system.py +182 -0
  572. services/work_order_agent/tracking/state_machine.py +163 -0
  573. services/work_order_agent/tracking/state_machine_integrator.py +295 -0
  574. services/work_order_agent/tracking/test_phase2_implementation.py +302 -0
  575. services/work_order_agent/tracking/time_analysis.py +301 -0
  576. services/work_order_agent/tracking/tracked_work_order.py +255 -0
  577. services/work_order_agent/tracking/work_order_adapter.py +367 -0
  578. services/work_order_agent/tracking/work_order_batch_manager.py +406 -0
  579. services/work_order_agent/tracking/work_order_repository.py +431 -0
  580. services/workorders/helpers/__init__.py +5 -0
  581. services/workorders/helpers/area_room_usage_ledger.py +139 -0
  582. services/workorders/helpers/batch_execution_records.py +265 -0
  583. services/workorders/helpers/batch_release_workflows.py +158 -0
  584. services/workorders/helpers/batch_step_executions.py +145 -0
  585. services/workorders/helpers/equipment_usage_ledger.py +209 -0
  586. services/workorders/helpers/executed_bmr_records.py +170 -0
  587. services/workorders/helpers/executed_bpr_records.py +170 -0
  588. services/workorders/helpers/executed_instruction_evidence.py +155 -0
  589. services/workorders/helpers/ipc_result_records.py +134 -0
  590. services/workorders/helpers/production_batches.py +117 -0
  591. services/workorders/helpers/work_orders.py +367 -0
  592. services/workorders/helpers/yield_reconciliation_records.py +158 -0
  593. services/workorders/main.py +110 -0
  594. services/workorders/models/__init__.py +5 -0
  595. services/workorders/models/area_room_usage_ledger.py +154 -0
  596. services/workorders/models/batch_execution_records.py +575 -0
  597. services/workorders/models/batch_release_workflows.py +190 -0
  598. services/workorders/models/batch_step_executions.py +142 -0
  599. services/workorders/models/equipment_usage_ledger.py +144 -0
  600. services/workorders/models/executed_bmr_records.py +220 -0
  601. services/workorders/models/executed_bpr_records.py +220 -0
  602. services/workorders/models/executed_instruction_evidence.py +128 -0
  603. services/workorders/models/ipc_result_records.py +164 -0
  604. services/workorders/models/production_batches.py +181 -0
  605. services/workorders/models/work_orders.py +255 -0
  606. services/workorders/models/yield_reconciliation_records.py +175 -0
  607. services/workorders/routers/__init__.py +5 -0
  608. services/workorders/routers/area_room_usage_ledger.py +117 -0
  609. services/workorders/routers/batch_execution_records.py +103 -0
  610. services/workorders/routers/batch_release_workflows.py +86 -0
  611. services/workorders/routers/batch_step_executions.py +88 -0
  612. services/workorders/routers/equipment_usage_ledger.py +115 -0
  613. services/workorders/routers/executed_bmr_records.py +86 -0
  614. services/workorders/routers/executed_bpr_records.py +86 -0
  615. services/workorders/routers/executed_instruction_evidence.py +86 -0
  616. services/workorders/routers/ipc_result_records.py +86 -0
  617. services/workorders/routers/production_batches.py +86 -0
  618. services/workorders/routers/work_orders.py +257 -0
  619. services/workorders/routers/yield_reconciliation_records.py +86 -0
  620. src/broca/__init__.py +5 -0
  621. src/broca/agent.py +201 -0
  622. src/cerebellum/__init__.py +0 -0
  623. src/cerebellum/adapter.py +84 -0
  624. src/cerebellum/capabilities/__init__.py +0 -0
  625. src/cerebellum/capabilities/agent/__init__.py +0 -0
  626. src/cerebellum/capabilities/agent/agents.py +65 -0
  627. src/cerebellum/capabilities/ai/__init__.py +0 -0
  628. src/cerebellum/capabilities/ai/providers.py +106 -0
  629. src/cerebellum/capabilities/api/__init__.py +0 -0
  630. src/cerebellum/capabilities/api/graphql.py +35 -0
  631. src/cerebellum/capabilities/api/rest_api.py +45 -0
  632. src/cerebellum/capabilities/api/webhook.py +30 -0
  633. src/cerebellum/capabilities/browser/__init__.py +0 -0
  634. src/cerebellum/capabilities/browser/browsers.py +27 -0
  635. src/cerebellum/capabilities/cloud/__init__.py +0 -0
  636. src/cerebellum/capabilities/cloud/cloud.py +46 -0
  637. src/cerebellum/capabilities/communication/__init__.py +0 -0
  638. src/cerebellum/capabilities/communication/communication.py +62 -0
  639. src/cerebellum/capabilities/database/__init__.py +0 -0
  640. src/cerebellum/capabilities/database/elasticsearch.py +40 -0
  641. src/cerebellum/capabilities/database/influxdb.py +37 -0
  642. src/cerebellum/capabilities/database/mongodb.py +50 -0
  643. src/cerebellum/capabilities/database/neo4j.py +32 -0
  644. src/cerebellum/capabilities/database/redis.py +44 -0
  645. src/cerebellum/capabilities/enterprise/__init__.py +0 -0
  646. src/cerebellum/capabilities/enterprise/opensource.py +180 -0
  647. src/cerebellum/capabilities/enterprise/proprietary.py +313 -0
  648. src/cerebellum/capabilities/event_streaming/__init__.py +0 -0
  649. src/cerebellum/capabilities/event_streaming/streaming.py +38 -0
  650. src/cerebellum/capabilities/infrastructure/__init__.py +0 -0
  651. src/cerebellum/capabilities/infrastructure/infrastructure.py +30 -0
  652. src/cerebellum/capabilities/productivity/__init__.py +0 -0
  653. src/cerebellum/capabilities/productivity/productivity.py +158 -0
  654. src/cerebellum/capabilities/robotics/__init__.py +0 -0
  655. src/cerebellum/capabilities/robotics/robotics.py +124 -0
  656. src/cerebellum/capabilities/runtime/__init__.py +0 -0
  657. src/cerebellum/capabilities/runtime/runtimes.py +92 -0
  658. src/cerebellum/capabilities/search/__init__.py +0 -0
  659. src/cerebellum/capabilities/search/search.py +63 -0
  660. src/cerebellum/capabilities/source_control/__init__.py +0 -0
  661. src/cerebellum/capabilities/source_control/source_control.py +113 -0
  662. src/cerebellum/capabilities/storage/__init__.py +0 -0
  663. src/cerebellum/capabilities/storage/storage.py +94 -0
  664. src/cerebellum/capabilities/workflow/__init__.py +0 -0
  665. src/cerebellum/capabilities/workflow/workflows.py +49 -0
  666. src/cerebellum/capability.py +108 -0
  667. src/cerebellum/config.py +157 -0
  668. src/cerebellum/fallback.py +147 -0
  669. src/cerebellum/fallback_engine.py +121 -0
  670. src/cerebellum/key_manager.py +129 -0
  671. src/cerebellum/keystore.py +179 -0
  672. src/cerebellum/lifecycle.py +54 -0
  673. src/cerebellum/metadata.py +61 -0
  674. src/cerebellum/operator/base.py +25 -0
  675. src/cerebellum/peripheral.py +92 -0
  676. src/cerebellum/registry.py +98 -0
  677. src/cerebellum/resolve_entity_capability.py +259 -0
  678. src/cingulate/benchmark/__init__.py +23 -0
  679. src/cingulate/benchmark/reporter.py +102 -0
  680. src/cingulate/benchmark/runner.py +159 -0
  681. src/cingulate/benchmark/scenario_runner.py +150 -0
  682. src/cingulate/benchmark/validator.py +102 -0
  683. src/cingulate/governance/__init__.py +21 -0
  684. src/cingulate/governance/architecture_validator.py +194 -0
  685. src/cingulate/governance/compliance.py +104 -0
  686. src/cingulate/governance/governance.py +77 -0
  687. src/cingulate/governance/policy_registry.py +91 -0
  688. src/cortex/__init__.py +33 -0
  689. src/cortex/cost.py +71 -0
  690. src/cortex/counterfactual.py +162 -0
  691. src/cortex/digital_twin.py +90 -0
  692. src/cortex/experience.py +83 -0
  693. src/cortex/feedback.py +144 -0
  694. src/cortex/loss.py +116 -0
  695. src/cortex/prediction.py +142 -0
  696. src/cortex/replay.py +130 -0
  697. src/cortex/reward.py +113 -0
  698. src/cortex/simulator.py +102 -0
  699. src/cortex/world_model.py +180 -0
  700. src/cortex/world_model_simulation.py +1591 -0
  701. src/cortex/world_state.py +121 -0
  702. src/cortex/xavier.py +250 -0
  703. src/deepdive/__init__.py +29 -0
  704. src/deepdive/aggregation.py +113 -0
  705. src/deepdive/digital_twin_aggregator.py +128 -0
  706. src/deepdive/elasticsearch_adapter.py +110 -0
  707. src/deepdive/fleet_analytics.py +131 -0
  708. src/deepdive/knowledge_aggregator.py +130 -0
  709. src/homeostasis/__init__.py +19 -0
  710. src/homeostasis/control_plane.py +159 -0
  711. src/introspection/__init__.py +38 -0
  712. src/introspection/alerting.py +142 -0
  713. src/introspection/health.py +101 -0
  714. src/introspection/lemon.py +243 -0
  715. src/introspection/logging.py +147 -0
  716. src/introspection/metrics.py +106 -0
  717. src/introspection/tracing.py +162 -0
  718. src/monkey_brain/__init__.py +1 -0
  719. src/monkey_brain/api/main.py +148 -0
  720. src/monkey_brain/api/models.py +81 -0
  721. src/monkey_brain/api/routes/routes/keys.py +106 -0
  722. src/monkey_brain/api/routes/routes/run.py +169 -0
  723. src/monkey_brain/api/routes/routes/simulate.py +485 -0
  724. src/monkey_brain/dlm/__init__.py +44 -0
  725. src/monkey_brain/dlm/dlm.py +139 -0
  726. src/monkey_brain/dlm/gc.py +115 -0
  727. src/monkey_brain/dlm/lifecycle.py +149 -0
  728. src/monkey_brain/dlm/orphans.py +99 -0
  729. src/monkey_brain/dlm/storage.py +149 -0
  730. src/monkey_brain/dlm/ttl.py +140 -0
  731. src/monkey_brain/documents/__init__.py +0 -0
  732. src/monkey_brain/documents/document_ocr.py +6 -0
  733. src/monkey_brain/kernel/__init__.py +53 -0
  734. src/monkey_brain/kernel/capability_interface.py +144 -0
  735. src/monkey_brain/kernel/classifier/__init__.py +1 -0
  736. src/monkey_brain/kernel/classifier/embed_classifier.py +125 -0
  737. src/monkey_brain/kernel/classifier/intent_examples.py +106 -0
  738. src/monkey_brain/kernel/dag.py +23 -0
  739. src/monkey_brain/kernel/execution_state.py +257 -0
  740. src/monkey_brain/kernel/goal_planner.py +85 -0
  741. src/monkey_brain/kernel/goal_router.py +20 -0
  742. src/monkey_brain/kernel/goals/__init__.py +1 -0
  743. src/monkey_brain/kernel/goals/goal.py +130 -0
  744. src/monkey_brain/kernel/goals/goal_bootstrap.py +38 -0
  745. src/monkey_brain/kernel/goals/goal_classifier.py +132 -0
  746. src/monkey_brain/kernel/goals/goal_registry.py +75 -0
  747. src/monkey_brain/kernel/intents/__init__.py +1 -0
  748. src/monkey_brain/kernel/intents/event_adapter.py +246 -0
  749. src/monkey_brain/kernel/intents/helpers.py +13 -0
  750. src/monkey_brain/kernel/intents/intent_registry.py +705 -0
  751. src/monkey_brain/kernel/intents/intent_router.py +102 -0
  752. src/monkey_brain/kernel/intents/predicates/approval_create.py +9 -0
  753. src/monkey_brain/kernel/intents/predicates/approval_decision.py +9 -0
  754. src/monkey_brain/kernel/intents/predicates/approval_hold.py +9 -0
  755. src/monkey_brain/kernel/intents/predicates/approval_query.py +9 -0
  756. src/monkey_brain/kernel/intents/predicates/batch_close.py +9 -0
  757. src/monkey_brain/kernel/intents/predicates/batch_creation.py +9 -0
  758. src/monkey_brain/kernel/intents/predicates/batch_delete.py +9 -0
  759. src/monkey_brain/kernel/intents/predicates/batch_hold.py +9 -0
  760. src/monkey_brain/kernel/intents/predicates/batch_record.py +9 -0
  761. src/monkey_brain/kernel/intents/predicates/batch_update.py +9 -0
  762. src/monkey_brain/kernel/intents/predicates/change_control.py +49 -0
  763. src/monkey_brain/kernel/intents/predicates/compliance_audit.py +14 -0
  764. src/monkey_brain/kernel/intents/predicates/decision_intelligence.py +9 -0
  765. src/monkey_brain/kernel/intents/predicates/drug_research.py +9 -0
  766. src/monkey_brain/kernel/intents/predicates/fuzzy_match.py +19 -0
  767. src/monkey_brain/kernel/intents/predicates/production_kpi.py +9 -0
  768. src/monkey_brain/kernel/intents/predicates/sop_create.py +9 -0
  769. src/monkey_brain/kernel/intents/predicates/sop_query.py +9 -0
  770. src/monkey_brain/kernel/intents/predicates/sop_update.py +9 -0
  771. src/monkey_brain/kernel/intents/predicates/warehouse_shipping.py +9 -0
  772. src/monkey_brain/kernel/intents/predicates/work_order_create.py +9 -0
  773. src/monkey_brain/kernel/intents/predicates/work_order_delete.py +9 -0
  774. src/monkey_brain/kernel/intents/predicates/work_order_hold.py +9 -0
  775. src/monkey_brain/kernel/intents/predicates/work_order_query.py +9 -0
  776. src/monkey_brain/kernel/intents/predicates/work_order_status.py +9 -0
  777. src/monkey_brain/kernel/intents/predicates/work_order_update.py +9 -0
  778. src/monkey_brain/kernel/intents/predicates/worker.py +9 -0
  779. src/monkey_brain/kernel/intents/telemetry_adapter.py +274 -0
  780. src/monkey_brain/kernel/intents/utils.py +68 -0
  781. src/monkey_brain/kernel/learning.py +98 -0
  782. src/monkey_brain/kernel/llm_explorer.py +188 -0
  783. src/monkey_brain/kernel/loss.py +81 -0
  784. src/monkey_brain/kernel/nlp/__init__.py +1 -0
  785. src/monkey_brain/kernel/nlp/compat.py +23 -0
  786. src/monkey_brain/kernel/nlp/models.py +10 -0
  787. src/monkey_brain/kernel/nlp/question_analyzer.py +203 -0
  788. src/monkey_brain/kernel/nlp/spacy_parser.py +53 -0
  789. src/monkey_brain/kernel/observer.py +97 -0
  790. src/monkey_brain/kernel/parser/__init__.py +3 -0
  791. src/monkey_brain/kernel/parser/ast.py +28 -0
  792. src/monkey_brain/kernel/parser/extractors/__init__.py +11 -0
  793. src/monkey_brain/kernel/parser/extractors/entities.py +21 -0
  794. src/monkey_brain/kernel/parser/extractors/filters.py +16 -0
  795. src/monkey_brain/kernel/parser/extractors/projections.py +36 -0
  796. src/monkey_brain/kernel/parser/extractors/verbs.py +31 -0
  797. src/monkey_brain/kernel/parser/parser.py +57 -0
  798. src/monkey_brain/kernel/parser/rules.py +75 -0
  799. src/monkey_brain/kernel/pipeline.py +44 -0
  800. src/monkey_brain/kernel/planner.py +57 -0
  801. src/monkey_brain/kernel/rl/__init__.py +33 -0
  802. src/monkey_brain/kernel/rl/learner.py +98 -0
  803. src/monkey_brain/kernel/rl/policy.py +254 -0
  804. src/monkey_brain/kernel/rl/reward.py +117 -0
  805. src/monkey_brain/kernel/rl/transition.py +112 -0
  806. src/monkey_brain/persistence/__init__.py +47 -0
  807. src/monkey_brain/persistence/adapters.py +49 -0
  808. src/monkey_brain/persistence/events.py +105 -0
  809. src/monkey_brain/persistence/manager.py +124 -0
  810. src/monkey_brain/persistence/mongodb_adapter.py +91 -0
  811. src/monkey_brain/persistence/redis_adapter.py +93 -0
  812. src/monkey_brain/persistence/reducer.py +111 -0
  813. src/monkey_brain/runtime/__init__.py +49 -0
  814. src/monkey_brain/runtime/depedencies.py +8 -0
  815. src/monkey_brain/runtime/engine.py +183 -0
  816. src/monkey_brain/runtime/message_bus.py +82 -0
  817. src/monkey_brain/runtime/process.py +144 -0
  818. src/monkey_brain/runtime/resource_manager.py +100 -0
  819. src/monkey_brain/runtime/routers.py +8 -0
  820. src/monkey_brain/runtime/runtime.py +199 -0
  821. src/monkey_brain/runtime/scheduler.py +165 -0
  822. src/monkey_brain/runtime/supervisor.py +133 -0
  823. src/monkey_brain/runtime/worker_pool.py +111 -0
  824. src/plasticity/seed/__init__.py +30 -0
  825. src/plasticity/seed/benchmark_generator.py +105 -0
  826. src/plasticity/seed/event_generator.py +122 -0
  827. src/plasticity/seed/scenario_builder.py +134 -0
  828. src/plasticity/seed/seed_data.py +206 -0
  829. src/plasticity/seed/seeder.py +122 -0
  830. src/plasticity/testing/__init__.py +28 -0
  831. src/plasticity/testing/performance.py +131 -0
  832. src/plasticity/testing/profiler.py +255 -0
  833. src/plasticity/testing/reporter.py +84 -0
  834. src/plasticity/testing/runner.py +209 -0
  835. src/sync/__init__.py +12 -0
  836. src/sync/cloud_aggregator.py +63 -0
  837. src/sync/edge_node.py +51 -0
  838. src/sync/sync_manager.py +74 -0
@@ -0,0 +1,152 @@
1
+ from datetime import date, datetime, timezone
2
+ from decimal import Decimal
3
+ from enum import Enum
4
+ from typing import Annotated, Optional
5
+ from uuid import UUID, uuid4
6
+
7
+ from pydantic import BaseModel, Field, computed_field, model_validator
8
+
9
+ from services.shipping.models.delivery_note import DeliveryStatus
10
+
11
+
12
+ def utc_now() -> datetime:
13
+ return datetime.now(timezone.utc)
14
+
15
+
16
+ class PackageType(str, Enum):
17
+ BOX = "box"
18
+ CARTON = "carton"
19
+ DRUM = "drum"
20
+ BAG = "bag"
21
+ CRATE = "crate"
22
+ TOTE = "tote"
23
+ ENVELOPE = "envelope"
24
+ OTHER = "other"
25
+
26
+
27
+ class PackageItem(BaseModel):
28
+ """Product line packed inside a package."""
29
+
30
+ line_number: int = Field(..., ge=1)
31
+ product_code: str = Field(..., max_length=50)
32
+ description: str = Field(..., max_length=255)
33
+ batch_number: Optional[str] = Field(None, max_length=50)
34
+ serial_number: Optional[str] = Field(None, max_length=100)
35
+ expiry_date: Optional[date] = None
36
+ quantity: Annotated[Decimal, Field(gt=0)]
37
+ uom: str = Field(..., max_length=20)
38
+ unit_weight_kg: Optional[float] = Field(None, ge=0)
39
+ hazardous: bool = False
40
+ un_number: Optional[str] = Field(None, max_length=4)
41
+
42
+ model_config = {"str_strip_whitespace": True}
43
+
44
+
45
+ class Package(BaseModel):
46
+ """Individual physical parcel, box, drum, or other container."""
47
+
48
+ id: UUID = Field(default_factory=uuid4)
49
+ package_code: str = Field(..., max_length=80, description="Barcode / tracking reference")
50
+ package_type: PackageType = PackageType.BOX
51
+ pallet_id: Optional[str] = Field(None, max_length=100)
52
+ delivery_note_id: Optional[str] = Field(None, max_length=100)
53
+ length_mm: Optional[int] = Field(None, gt=0)
54
+ width_mm: Optional[int] = Field(None, gt=0)
55
+ height_mm: Optional[int] = Field(None, gt=0)
56
+ gross_weight_kg: Optional[float] = Field(None, ge=0)
57
+ net_weight_kg: Optional[float] = Field(None, ge=0)
58
+ items: list[PackageItem] = Field(default_factory=list)
59
+ is_fragile: bool = False
60
+ is_hazardous: bool = False
61
+ un_number: Optional[str] = Field(None, max_length=4)
62
+ do_not_stack: bool = False
63
+ requires_refrigeration: bool = False
64
+ temp_min_celsius: Optional[float] = None
65
+ temp_max_celsius: Optional[float] = None
66
+ tracking_number: Optional[str] = Field(None, max_length=100)
67
+ status: DeliveryStatus = DeliveryStatus.PENDING
68
+ notes: Optional[str] = None
69
+ created_at: datetime = Field(default_factory=utc_now)
70
+ updated_at: Optional[datetime] = None
71
+
72
+ model_config = {"str_strip_whitespace": True}
73
+
74
+ @computed_field # type: ignore[misc]
75
+ @property
76
+ def volume_cm3(self) -> Optional[float]:
77
+ if self.length_mm and self.width_mm and self.height_mm:
78
+ return round(self.length_mm * self.width_mm * self.height_mm / 1_000, 2)
79
+ return None
80
+
81
+ @model_validator(mode="after")
82
+ def hazardous_needs_un(self) -> "Package":
83
+ if self.is_hazardous and not self.un_number:
84
+ raise ValueError("un_number required when is_hazardous is True")
85
+ return self
86
+
87
+ @model_validator(mode="after")
88
+ def refrigeration_range(self) -> "Package":
89
+ if self.requires_refrigeration:
90
+ if self.temp_min_celsius is None or self.temp_max_celsius is None:
91
+ raise ValueError("temp_min/max_celsius required when requires_refrigeration is True")
92
+ if self.temp_min_celsius >= self.temp_max_celsius:
93
+ raise ValueError("temp_min_celsius must be less than temp_max_celsius")
94
+ return self
95
+
96
+
97
+ class PackageCreate(Package):
98
+ pass
99
+
100
+
101
+ class PackageUpdate(BaseModel):
102
+ package_code: Optional[str] = Field(None, max_length=80)
103
+ package_type: Optional[PackageType] = None
104
+ pallet_id: Optional[str] = Field(None, max_length=100)
105
+ delivery_note_id: Optional[str] = Field(None, max_length=100)
106
+ length_mm: Optional[int] = Field(None, gt=0)
107
+ width_mm: Optional[int] = Field(None, gt=0)
108
+ height_mm: Optional[int] = Field(None, gt=0)
109
+ gross_weight_kg: Optional[float] = Field(None, ge=0)
110
+ net_weight_kg: Optional[float] = Field(None, ge=0)
111
+ items: Optional[list[PackageItem]] = None
112
+ is_fragile: Optional[bool] = None
113
+ is_hazardous: Optional[bool] = None
114
+ un_number: Optional[str] = Field(None, max_length=4)
115
+ do_not_stack: Optional[bool] = None
116
+ requires_refrigeration: Optional[bool] = None
117
+ temp_min_celsius: Optional[float] = None
118
+ temp_max_celsius: Optional[float] = None
119
+ tracking_number: Optional[str] = Field(None, max_length=100)
120
+ status: Optional[DeliveryStatus] = None
121
+ notes: Optional[str] = None
122
+ updated_at: Optional[datetime] = None
123
+
124
+ model_config = {"str_strip_whitespace": True}
125
+
126
+ @model_validator(mode="after")
127
+ def hazardous_needs_un(self) -> "PackageUpdate":
128
+ if self.is_hazardous is True and not self.un_number:
129
+ raise ValueError("un_number required when is_hazardous is True")
130
+ return self
131
+
132
+ @model_validator(mode="after")
133
+ def refrigeration_range(self) -> "PackageUpdate":
134
+ if self.requires_refrigeration is True:
135
+ if self.temp_min_celsius is None or self.temp_max_celsius is None:
136
+ raise ValueError("temp_min/max_celsius required when requires_refrigeration is True")
137
+ if self.temp_min_celsius is not None and self.temp_max_celsius is not None:
138
+ if self.temp_min_celsius >= self.temp_max_celsius:
139
+ raise ValueError("temp_min_celsius must be less than temp_max_celsius")
140
+ return self
141
+
142
+
143
+ class PackageResponse(Package):
144
+ class Config:
145
+ from_attributes = True
146
+
147
+
148
+ class PaginatedPackageResponse(BaseModel):
149
+ total: int
150
+ page: int
151
+ page_size: int
152
+ results: list[PackageResponse]
@@ -0,0 +1,137 @@
1
+ from decimal import Decimal
2
+ from enum import Enum
3
+ from typing import Annotated, Optional
4
+ from uuid import UUID, uuid4
5
+
6
+ from pydantic import BaseModel, Field, computed_field, model_validator
7
+
8
+
9
+ class PalletType(str, Enum):
10
+ EURO = "euro"
11
+ STANDARD = "standard"
12
+ BLOCK = "block"
13
+ STRINGER = "stringer"
14
+ PLASTIC = "plastic"
15
+ CUSTOM = "custom"
16
+
17
+
18
+ class PalletCondition(str, Enum):
19
+ GOOD = "good"
20
+ DAMAGED = "damaged"
21
+ REPAIRED = "repaired"
22
+ QUARANTINED = "quarantined"
23
+ DISPOSED = "disposed"
24
+
25
+
26
+ class PalletDimensions(BaseModel):
27
+ """Physical pallet dimensions (millimetres)."""
28
+
29
+ length_mm: Annotated[int, Field(gt=0)]
30
+ width_mm: Annotated[int, Field(gt=0)]
31
+ height_mm: Annotated[int, Field(gt=0)]
32
+
33
+
34
+ class PalletContent(BaseModel):
35
+ """Line item loaded onto a pallet."""
36
+
37
+ line_number: int = Field(..., ge=1)
38
+ product_code: str = Field(..., min_length=1, max_length=50)
39
+ product_description: str = Field(..., max_length=255)
40
+ batch_number: Optional[str] = Field(None, max_length=50)
41
+ quantity: Annotated[Decimal, Field(gt=0)]
42
+ unit_of_measure: str = Field(..., max_length=20, examples=["EA", "KG", "L", "M"])
43
+ gross_weight_kg: Optional[Annotated[float, Field(ge=0)]] = None
44
+ net_weight_kg: Optional[Annotated[float, Field(ge=0)]] = None
45
+ hazardous: bool = False
46
+ un_number: Optional[str] = Field(
47
+ None, max_length=4, description="UN hazmat number if hazardous"
48
+ )
49
+
50
+
51
+ class Pallet(BaseModel):
52
+ """Individual pallet / loading unit."""
53
+
54
+ id: UUID = Field(default_factory=uuid4)
55
+ pallet_label: str = Field(..., min_length=1, max_length=50, description="Barcode / SSCC label")
56
+ pallet_type: PalletType = PalletType.EURO
57
+ condition: PalletCondition = PalletCondition.GOOD
58
+ dimensions: Optional[PalletDimensions] = None
59
+ tare_weight_kg: Optional[Annotated[float, Field(ge=0)]] = None
60
+ max_load_kg: Optional[Annotated[float, Field(gt=0)]] = None
61
+ contents: list[PalletContent] = Field(default_factory=list)
62
+ is_stackable: bool = True
63
+ stack_limit: Optional[int] = Field(None, ge=1, description="Max units that can be stacked on top")
64
+ stretch_wrapped: bool = False
65
+ temperature_controlled: bool = False
66
+ temperature_min_celsius: Optional[float] = None
67
+ temperature_max_celsius: Optional[float] = None
68
+ notes: Optional[str] = None
69
+
70
+ model_config = {"str_strip_whitespace": True}
71
+
72
+ @computed_field # type: ignore[misc]
73
+ @property
74
+ def total_gross_weight_kg(self) -> float:
75
+ tare = self.tare_weight_kg or 0.0
76
+ payload = sum(c.gross_weight_kg or 0 for c in self.contents)
77
+ return round(tare + payload, 3)
78
+
79
+ @model_validator(mode="after")
80
+ def validate_temperature_fields(self) -> "Pallet":
81
+ if self.temperature_controlled:
82
+ if self.temperature_min_celsius is None or self.temperature_max_celsius is None:
83
+ raise ValueError(
84
+ "temperature_min_celsius and temperature_max_celsius are required "
85
+ "when temperature_controlled is True"
86
+ )
87
+ if self.temperature_min_celsius >= self.temperature_max_celsius:
88
+ raise ValueError("temperature_min_celsius must be less than temperature_max_celsius")
89
+ return self
90
+
91
+
92
+ class PalletCreate(Pallet):
93
+ pass
94
+
95
+
96
+ class PalletUpdate(BaseModel):
97
+ pallet_label: Optional[str] = Field(None, min_length=1, max_length=50)
98
+ pallet_type: Optional[PalletType] = None
99
+ condition: Optional[PalletCondition] = None
100
+ dimensions: Optional[PalletDimensions] = None
101
+ tare_weight_kg: Optional[Annotated[float, Field(ge=0)]] = None
102
+ max_load_kg: Optional[Annotated[float, Field(gt=0)]] = None
103
+ contents: Optional[list[PalletContent]] = None
104
+ is_stackable: Optional[bool] = None
105
+ stack_limit: Optional[int] = Field(None, ge=1)
106
+ stretch_wrapped: Optional[bool] = None
107
+ temperature_controlled: Optional[bool] = None
108
+ temperature_min_celsius: Optional[float] = None
109
+ temperature_max_celsius: Optional[float] = None
110
+ notes: Optional[str] = None
111
+
112
+ model_config = {"str_strip_whitespace": True}
113
+
114
+ @model_validator(mode="after")
115
+ def validate_temperature_fields(self) -> "PalletUpdate":
116
+ if self.temperature_controlled is True:
117
+ if self.temperature_min_celsius is None or self.temperature_max_celsius is None:
118
+ raise ValueError(
119
+ "temperature_min_celsius and temperature_max_celsius are required "
120
+ "when temperature_controlled is True"
121
+ )
122
+ if self.temperature_min_celsius is not None and self.temperature_max_celsius is not None:
123
+ if self.temperature_min_celsius >= self.temperature_max_celsius:
124
+ raise ValueError("temperature_min_celsius must be less than temperature_max_celsius")
125
+ return self
126
+
127
+
128
+ class PalletResponse(Pallet):
129
+ class Config:
130
+ from_attributes = True
131
+
132
+
133
+ class PaginatedPalletResponse(BaseModel):
134
+ total: int
135
+ page: int
136
+ page_size: int
137
+ results: list[PalletResponse]
@@ -0,0 +1,120 @@
1
+ from datetime import date, datetime, timezone
2
+ from enum import Enum
3
+ from typing import Optional
4
+ from uuid import UUID, uuid4
5
+
6
+ from pydantic import BaseModel, Field, model_validator
7
+
8
+ from services.shipping.models.carrier import Address
9
+
10
+
11
+ def utc_now() -> datetime:
12
+ return datetime.now(timezone.utc)
13
+
14
+
15
+ class RouteStopType(str, Enum):
16
+ PICKUP = "pickup"
17
+ DELIVERY = "delivery"
18
+ TRANSFER = "transfer"
19
+ RETURN = "return"
20
+ DEPOT = "depot"
21
+ BREAK = "break"
22
+
23
+
24
+ class GeoCoordinate(BaseModel):
25
+ latitude: float = Field(..., ge=-90, le=90)
26
+ longitude: float = Field(..., ge=-180, le=180)
27
+
28
+
29
+ class RouteStop(BaseModel):
30
+ """A single stop on a planned delivery route."""
31
+
32
+ stop_sequence: int = Field(..., ge=1)
33
+ stop_type: RouteStopType
34
+ name: str = Field(..., max_length=200)
35
+ address: Address
36
+ coordinates: Optional[GeoCoordinate] = None
37
+ planned_arrival: Optional[datetime] = None
38
+ planned_departure: Optional[datetime] = None
39
+ actual_arrival: Optional[datetime] = None
40
+ actual_departure: Optional[datetime] = None
41
+ delivery_note_ids: list[str] = Field(default_factory=list)
42
+ pallet_ids_to_load: list[str] = Field(default_factory=list)
43
+ pallet_ids_to_unload: list[str] = Field(default_factory=list)
44
+ contact_name: Optional[str] = Field(None, max_length=150)
45
+ contact_phone: Optional[str] = Field(None, max_length=30)
46
+ special_instructions: Optional[str] = None
47
+ completed: bool = False
48
+
49
+
50
+ class Route(BaseModel):
51
+ """Planned multi-stop delivery route assigned to a vehicle and driver."""
52
+
53
+ id: UUID = Field(default_factory=uuid4)
54
+ route_reference: str = Field(..., min_length=1, max_length=80)
55
+ planned_date: date
56
+ vehicle_id: Optional[str] = Field(None, max_length=100)
57
+ driver_id: Optional[str] = Field(None, max_length=100)
58
+ carrier_id: Optional[str] = Field(None, max_length=100)
59
+ stops: list[RouteStop] = Field(default_factory=list, min_length=1)
60
+ total_distance_km: Optional[float] = Field(None, ge=0)
61
+ estimated_duration_hours: Optional[float] = Field(None, ge=0)
62
+ actual_distance_km: Optional[float] = Field(None, ge=0)
63
+ actual_duration_hours: Optional[float] = Field(None, ge=0)
64
+ fuel_consumption_l: Optional[float] = Field(None, ge=0)
65
+ completed: bool = False
66
+ notes: Optional[str] = None
67
+ created_at: datetime = Field(default_factory=utc_now)
68
+ updated_at: Optional[datetime] = None
69
+
70
+ model_config = {"str_strip_whitespace": True}
71
+
72
+ @model_validator(mode="after")
73
+ def stops_in_sequence(self) -> "Route":
74
+ seqs = [stop.stop_sequence for stop in self.stops]
75
+ if len(seqs) != len(set(seqs)):
76
+ raise ValueError("stop_sequence values must be unique within a route")
77
+ return self
78
+
79
+
80
+ class RouteCreate(Route):
81
+ pass
82
+
83
+
84
+ class RouteUpdate(BaseModel):
85
+ route_reference: Optional[str] = Field(None, min_length=1, max_length=80)
86
+ planned_date: Optional[date] = None
87
+ vehicle_id: Optional[str] = Field(None, max_length=100)
88
+ driver_id: Optional[str] = Field(None, max_length=100)
89
+ carrier_id: Optional[str] = Field(None, max_length=100)
90
+ stops: Optional[list[RouteStop]] = Field(None, min_length=1)
91
+ total_distance_km: Optional[float] = Field(None, ge=0)
92
+ estimated_duration_hours: Optional[float] = Field(None, ge=0)
93
+ actual_distance_km: Optional[float] = Field(None, ge=0)
94
+ actual_duration_hours: Optional[float] = Field(None, ge=0)
95
+ fuel_consumption_l: Optional[float] = Field(None, ge=0)
96
+ completed: Optional[bool] = None
97
+ notes: Optional[str] = None
98
+ updated_at: Optional[datetime] = None
99
+
100
+ model_config = {"str_strip_whitespace": True}
101
+
102
+ @model_validator(mode="after")
103
+ def stops_in_sequence(self) -> "RouteUpdate":
104
+ if self.stops is not None:
105
+ seqs = [stop.stop_sequence for stop in self.stops]
106
+ if len(seqs) != len(set(seqs)):
107
+ raise ValueError("stop_sequence values must be unique within a route")
108
+ return self
109
+
110
+
111
+ class RouteResponse(Route):
112
+ class Config:
113
+ from_attributes = True
114
+
115
+
116
+ class PaginatedRouteResponse(BaseModel):
117
+ total: int
118
+ page: int
119
+ page_size: int
120
+ results: list[RouteResponse]
@@ -0,0 +1,55 @@
1
+ from datetime import datetime, timezone
2
+ from typing import Optional
3
+
4
+ from pydantic import BaseModel, Field
5
+
6
+
7
+ def datetime_now() -> datetime:
8
+ return datetime.now(timezone.utc)
9
+
10
+
11
+ class ShippingInformation(BaseModel):
12
+ order_id: str = Field(..., description="Unique identifier for the order")
13
+ shipping_id: str = Field(..., description="Unique identifier for the shipping record")
14
+ shipping_address: str = Field(..., description="Address where the component is being shipped to")
15
+ shipping_date: Optional[datetime] = Field(None, description="Date when the component was shipped")
16
+ expected_delivery_date: Optional[datetime] = Field(None, description="Date when the shipment is expected to arrive")
17
+ shipping_method: Optional[str] = Field(None, description="Method of shipment, for example Air, Sea, or Ground")
18
+ tracking_number: Optional[str] = Field(None, description="Tracking number provided by the shipping carrier")
19
+ carrier_name: Optional[str] = Field(None, description="Name of the shipping carrier or service")
20
+ shipment_status: Optional[str] = Field(None, description="Current status of the shipment")
21
+ weight: Optional[float] = Field(None, description="Weight of the shipment in kilograms")
22
+ shipping_cost: Optional[float] = Field(None, description="Cost of shipping the component")
23
+ insurance_details: Optional[str] = Field(None, description="Details about any insurance coverage for the shipment")
24
+ remarks: Optional[str] = Field(None, description="Additional notes or comments related to the shipment")
25
+
26
+
27
+ class ShippingInformationCreate(ShippingInformation):
28
+ pass
29
+
30
+
31
+ class ShippingInformationUpdate(BaseModel):
32
+ order_id: Optional[str] = None
33
+ shipping_address: Optional[str] = None
34
+ shipping_date: Optional[datetime] = None
35
+ expected_delivery_date: Optional[datetime] = None
36
+ shipping_method: Optional[str] = None
37
+ tracking_number: Optional[str] = None
38
+ carrier_name: Optional[str] = None
39
+ shipment_status: Optional[str] = None
40
+ weight: Optional[float] = None
41
+ shipping_cost: Optional[float] = None
42
+ insurance_details: Optional[str] = None
43
+ remarks: Optional[str] = None
44
+
45
+
46
+ class ShippingInformationResponse(ShippingInformation):
47
+ class Config:
48
+ from_attributes = True
49
+
50
+
51
+ class PaginatedShippingInformationResponse(BaseModel):
52
+ total: int
53
+ page: int
54
+ page_size: int
55
+ results: list[ShippingInformationResponse]
@@ -0,0 +1,42 @@
1
+ from typing import Optional
2
+
3
+ from pydantic import BaseModel, Field
4
+
5
+
6
+ class ShippingProviderDetails(BaseModel):
7
+ provider_id: str = Field(..., description="Unique identifier for the shipping provider")
8
+ provider_name: str = Field(..., description="Name of the shipping provider or carrier")
9
+ contact_number: Optional[str] = Field(None, description="Contact phone number for the shipping provider")
10
+ email_address: Optional[str] = Field(None, description="Email address of the shipping provider")
11
+ address: Optional[str] = Field(None, description="Physical address of the shipping provider")
12
+ service_areas: Optional[str] = Field(None, description="Geographic regions or areas serviced by the provider")
13
+ available_services: Optional[str] = Field(None, description="Details of shipping services offered, for example Air Freight or Express Delivery")
14
+ rating: Optional[float] = Field(None, description="Customer rating of the shipping provider out of 5")
15
+ website_url: Optional[str] = Field(None, description="Website URL of the shipping provider")
16
+
17
+
18
+ class ShippingProviderDetailsCreate(ShippingProviderDetails):
19
+ pass
20
+
21
+
22
+ class ShippingProviderDetailsUpdate(BaseModel):
23
+ provider_name: Optional[str] = None
24
+ contact_number: Optional[str] = None
25
+ email_address: Optional[str] = None
26
+ address: Optional[str] = None
27
+ service_areas: Optional[str] = None
28
+ available_services: Optional[str] = None
29
+ rating: Optional[float] = None
30
+ website_url: Optional[str] = None
31
+
32
+
33
+ class ShippingProviderDetailsResponse(ShippingProviderDetails):
34
+ class Config:
35
+ from_attributes = True
36
+
37
+
38
+ class PaginatedShippingProviderDetailsResponse(BaseModel):
39
+ total: int
40
+ page: int
41
+ page_size: int
42
+ results: list[ShippingProviderDetailsResponse]
@@ -0,0 +1,54 @@
1
+ from typing import Optional
2
+
3
+ from pydantic import BaseModel, Field
4
+
5
+
6
+ class ShippingProviderMetadata(BaseModel):
7
+ provider_id: str = Field(..., description="Unique identifier for the shipping provider")
8
+ base_shipping_rate: Optional[float] = Field(None, description="Base cost for shipping services in the provider's pricing model")
9
+ cost_per_kg: Optional[float] = Field(None, description="Cost per kilogram for shipping")
10
+ cost_per_km: Optional[float] = Field(None, description="Cost per kilometer for shipping")
11
+ surcharge_details: Optional[str] = Field(None, description="Details of any surcharges, for example fuel surcharge or peak season fees")
12
+ fleet_details: Optional[list[str]] = Field(None, description="Details about the provider's fleet, for example trucks, ships, or drones")
13
+ average_delivery_time: Optional[str] = Field(None, description="Average delivery time for shipments handled by the provider, for example 3-5 business days")
14
+ pricing_model: Optional[str] = Field(None, description="Description of the provider's pricing model, for example flat rate, per kilogram, or per distance")
15
+ insurance_offered: Optional[bool] = Field(None, description="Indicates whether the provider offers insurance for shipments")
16
+ category: str = Field(..., description="The category of the logistics capability, for example Transportation or Warehousing.")
17
+ capabilities: str = Field(..., description="Specific capability under the category.")
18
+ description: str = Field(..., description="A detailed description of the capability.")
19
+ key_features: list[str] = Field(..., description="Key features of the capability.")
20
+ certifications: Optional[list[str]] = Field(None, description="Relevant certifications for the capability.")
21
+ remarks: Optional[str] = Field(None, description="Additional notes or comments related to the provider or capability.")
22
+
23
+
24
+ class ShippingProviderMetadataCreate(ShippingProviderMetadata):
25
+ pass
26
+
27
+
28
+ class ShippingProviderMetadataUpdate(BaseModel):
29
+ base_shipping_rate: Optional[float] = None
30
+ cost_per_kg: Optional[float] = None
31
+ cost_per_km: Optional[float] = None
32
+ surcharge_details: Optional[str] = None
33
+ fleet_details: Optional[list[str]] = None
34
+ average_delivery_time: Optional[str] = None
35
+ pricing_model: Optional[str] = None
36
+ insurance_offered: Optional[bool] = None
37
+ category: Optional[str] = None
38
+ capabilities: Optional[str] = None
39
+ description: Optional[str] = None
40
+ key_features: Optional[list[str]] = None
41
+ certifications: Optional[list[str]] = None
42
+ remarks: Optional[str] = None
43
+
44
+
45
+ class ShippingProviderMetadataResponse(ShippingProviderMetadata):
46
+ class Config:
47
+ from_attributes = True
48
+
49
+
50
+ class PaginatedShippingProviderMetadataResponse(BaseModel):
51
+ total: int
52
+ page: int
53
+ page_size: int
54
+ results: list[ShippingProviderMetadataResponse]
@@ -0,0 +1,129 @@
1
+ from datetime import date, datetime, timezone
2
+ from enum import Enum
3
+ from typing import Annotated, Optional
4
+ from uuid import UUID, uuid4
5
+
6
+ from pydantic import BaseModel, Field, model_validator
7
+
8
+
9
+ def utc_now() -> datetime:
10
+ return datetime.now(timezone.utc)
11
+
12
+
13
+ class VehicleType(str, Enum):
14
+ VAN = "van"
15
+ BOX_TRUCK = "box_truck"
16
+ FLATBED = "flatbed"
17
+ REFRIGERATED_TRUCK = "refrigerated_truck"
18
+ TANKER = "tanker"
19
+ TRAILER = "trailer"
20
+ CONTAINER = "container"
21
+ OTHER = "other"
22
+
23
+
24
+ class VehicleDimensions(BaseModel):
25
+ """Internal cargo dimensions (metres)."""
26
+
27
+ length_m: Annotated[float, Field(gt=0, le=25)]
28
+ width_m: Annotated[float, Field(gt=0, le=5)]
29
+ height_m: Annotated[float, Field(gt=0, le=5)]
30
+
31
+ @property
32
+ def volume_m3(self) -> float:
33
+ return round(self.length_m * self.width_m * self.height_m, 4)
34
+
35
+
36
+ class Vehicle(BaseModel):
37
+ """Transport vehicle belonging to a carrier or manufacturer fleet."""
38
+
39
+ id: UUID = Field(default_factory=uuid4)
40
+ carrier_id: Optional[str] = Field(None, description="Owning carrier; None = own fleet")
41
+ vehicle_type: VehicleType
42
+ registration_plate: str = Field(..., min_length=1, max_length=20)
43
+ vin: Optional[str] = Field(None, min_length=17, max_length=17, description="Vehicle Identification Number")
44
+ make: Optional[str] = Field(None, max_length=50)
45
+ model: Optional[str] = Field(None, max_length=50)
46
+ year: Optional[int] = Field(None, ge=1900, le=2100)
47
+ max_payload_kg: Annotated[float, Field(gt=0)]
48
+ max_volume_m3: Optional[Annotated[float, Field(gt=0)]] = None
49
+ cargo_dimensions: Optional[VehicleDimensions] = None
50
+ has_tail_lift: bool = False
51
+ is_refrigerated: bool = False
52
+ temperature_range_celsius: Optional[tuple[float, float]] = Field(
53
+ None, description="Min and max temp if refrigerated"
54
+ )
55
+ driver_name: Optional[str] = Field(None, max_length=150)
56
+ driver_license_number: Optional[str] = Field(None, max_length=50)
57
+ driver_phone: Optional[str] = Field(None, max_length=30)
58
+ mot_expiry: Optional[date] = Field(None, description="MOT / roadworthiness certificate expiry")
59
+ insurance_expiry: Optional[date] = None
60
+ gps_tracker_id: Optional[str] = Field(None, max_length=100)
61
+ active: bool = True
62
+ notes: Optional[str] = None
63
+ created_at: datetime = Field(default_factory=utc_now)
64
+ updated_at: Optional[datetime] = None
65
+
66
+ model_config = {"str_strip_whitespace": True}
67
+
68
+ @model_validator(mode="after")
69
+ def validate_temperature_range(self) -> "Vehicle":
70
+ if self.is_refrigerated and self.temperature_range_celsius is None:
71
+ raise ValueError("temperature_range_celsius is required for refrigerated vehicles")
72
+ if self.temperature_range_celsius is not None:
73
+ low, high = self.temperature_range_celsius
74
+ if low >= high:
75
+ raise ValueError("temperature_range_celsius[0] must be less than [1]")
76
+ return self
77
+
78
+
79
+ class VehicleCreate(Vehicle):
80
+ pass
81
+
82
+
83
+ class VehicleUpdate(BaseModel):
84
+ carrier_id: Optional[UUID] = None
85
+ vehicle_type: Optional[VehicleType] = None
86
+ registration_plate: Optional[str] = Field(None, min_length=1, max_length=20)
87
+ vin: Optional[str] = Field(None, min_length=17, max_length=17)
88
+ make: Optional[str] = Field(None, max_length=50)
89
+ model: Optional[str] = Field(None, max_length=50)
90
+ year: Optional[int] = Field(None, ge=1900, le=2100)
91
+ max_payload_kg: Optional[Annotated[float, Field(gt=0)]] = None
92
+ max_volume_m3: Optional[Annotated[float, Field(gt=0)]] = None
93
+ cargo_dimensions: Optional[VehicleDimensions] = None
94
+ has_tail_lift: Optional[bool] = None
95
+ is_refrigerated: Optional[bool] = None
96
+ temperature_range_celsius: Optional[tuple[float, float]] = None
97
+ driver_name: Optional[str] = Field(None, max_length=150)
98
+ driver_license_number: Optional[str] = Field(None, max_length=50)
99
+ driver_phone: Optional[str] = Field(None, max_length=30)
100
+ mot_expiry: Optional[date] = None
101
+ insurance_expiry: Optional[date] = None
102
+ gps_tracker_id: Optional[str] = Field(None, max_length=100)
103
+ active: Optional[bool] = None
104
+ notes: Optional[str] = None
105
+ updated_at: Optional[datetime] = None
106
+
107
+ model_config = {"str_strip_whitespace": True}
108
+
109
+ @model_validator(mode="after")
110
+ def validate_temperature_range(self) -> "VehicleUpdate":
111
+ if self.is_refrigerated is True and self.temperature_range_celsius is None:
112
+ raise ValueError("temperature_range_celsius is required for refrigerated vehicles")
113
+ if self.temperature_range_celsius is not None:
114
+ low, high = self.temperature_range_celsius
115
+ if low >= high:
116
+ raise ValueError("temperature_range_celsius[0] must be less than [1]")
117
+ return self
118
+
119
+
120
+ class VehicleResponse(Vehicle):
121
+ class Config:
122
+ from_attributes = True
123
+
124
+
125
+ class PaginatedVehicleResponse(BaseModel):
126
+ total: int
127
+ page: int
128
+ page_size: int
129
+ results: list[VehicleResponse]