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,220 @@
1
+ from datetime import datetime, timezone
2
+ from typing import Any, Literal, Optional
3
+
4
+ from pydantic import BaseModel, Field, model_validator
5
+
6
+
7
+ ExecutedBmrStatus = Literal["Draft", "In Progress", "Completed", "Under QA Review", "Approved", "Rejected", "Voided"]
8
+ ExecutedBmrSectionStatus = Literal["Pending", "In Progress", "Completed", "Skipped", "Rejected"]
9
+
10
+
11
+ def utc_now() -> datetime:
12
+ return datetime.now(timezone.utc)
13
+
14
+
15
+ def ensure_utc(value: Optional[datetime]) -> Optional[datetime]:
16
+ if value is None:
17
+ return None
18
+ if value.tzinfo is None:
19
+ return value.replace(tzinfo=timezone.utc)
20
+ return value.astimezone(timezone.utc)
21
+
22
+
23
+ def required_cleaning_coverage(metadata: dict[str, Any], cleaning_record_ids: list[str]) -> tuple[list[str], list[str]]:
24
+ required = [str(item) for item in metadata.get("required_cleaning_requirement_ids") or [] if item]
25
+ coverage = metadata.get("cleaning_requirement_record_map") if isinstance(metadata.get("cleaning_requirement_record_map"), dict) else {}
26
+ missing = [requirement_id for requirement_id in required if not coverage.get(requirement_id)]
27
+ referenced_records = {str(value) for value in coverage.values() if value}
28
+ missing_records = sorted(referenced_records.difference(set(cleaning_record_ids)))
29
+ return missing, missing_records
30
+
31
+
32
+ def missing_required_equipment_usage(metadata: dict[str, Any], equipment_usage_ids: list[str]) -> list[str]:
33
+ required = {str(item) for item in metadata.get("required_equipment_usage_ids") or [] if item}
34
+ attached = {str(item) for item in equipment_usage_ids if item}
35
+ return sorted(required.difference(attached))
36
+
37
+
38
+ class ExecutedBmrSection(BaseModel):
39
+ section_execution_id: str = Field(..., min_length=1)
40
+ template_section_id: str = Field(..., min_length=1)
41
+ sequence: int = Field(..., ge=1)
42
+ title: str = Field(..., min_length=1)
43
+ process_step_id: Optional[str] = None
44
+ stage_id: Optional[str] = None
45
+ workstation_id: Optional[str] = None
46
+ batch_step_execution_id: Optional[str] = None
47
+ status: ExecutedBmrSectionStatus = "Pending"
48
+ started_at: Optional[datetime] = None
49
+ completed_at: Optional[datetime] = None
50
+ performed_by: Optional[str] = None
51
+ verified_by: Optional[str] = None
52
+ actual_values: dict[str, Any] = Field(default_factory=dict)
53
+ executed_instruction_evidence_ids: list[str] = Field(default_factory=list)
54
+ evidence_document_ids: list[str] = Field(default_factory=list)
55
+ report_template_ids: list[str] = Field(default_factory=list)
56
+ report_template_section_ids: list[str] = Field(default_factory=list)
57
+ signature_ids: list[str] = Field(default_factory=list)
58
+ comments: Optional[str] = None
59
+
60
+ @model_validator(mode="after")
61
+ def normalize_and_validate(self) -> "ExecutedBmrSection":
62
+ self.started_at = ensure_utc(self.started_at)
63
+ self.completed_at = ensure_utc(self.completed_at)
64
+ if self.completed_at and self.started_at and self.completed_at < self.started_at:
65
+ raise ValueError("completed_at cannot be before started_at for an executed BMR section.")
66
+ if self.status == "Completed":
67
+ if not self.completed_at:
68
+ raise ValueError("completed executed BMR sections must include completed_at.")
69
+ if not self.performed_by:
70
+ raise ValueError("completed executed BMR sections must include performed_by.")
71
+ if not self.signature_ids:
72
+ raise ValueError("completed executed BMR sections must include signature_ids.")
73
+ return self
74
+
75
+
76
+ class ExecutedBatchManufacturingRecord(BaseModel):
77
+ executed_bmr_record_id: str = Field(..., min_length=1)
78
+ executed_bmr_document_id: str = Field(..., min_length=1)
79
+ batch_execution_record_id: str = Field(..., min_length=1)
80
+ batch_id: str = Field(..., min_length=1)
81
+ batch_number: Optional[str] = None
82
+
83
+ mbmr_template_id: str = Field(..., min_length=1)
84
+ mbmr_document_id: str = Field(..., min_length=1)
85
+ bmr_template_id: str = Field(..., min_length=1)
86
+ bmr_template_document_id: str = Field(..., min_length=1)
87
+ template_revision: Optional[str] = None
88
+ generated_from_approved_template: bool = False
89
+ generated_at: datetime = Field(default_factory=utc_now)
90
+
91
+ process_definition_id: str = Field(..., min_length=1)
92
+ process_route_id: Optional[str] = None
93
+ bom_id: str = Field(..., min_length=1)
94
+ product_id: Optional[str] = None
95
+ plant_id: Optional[str] = None
96
+ line_id: Optional[str] = None
97
+
98
+ status: ExecutedBmrStatus = "Draft"
99
+ sections: list[ExecutedBmrSection] = Field(default_factory=list)
100
+ batch_step_execution_ids: list[str] = Field(default_factory=list)
101
+ dispense_weighing_record_ids: list[str] = Field(default_factory=list)
102
+ cleaning_record_ids: list[str] = Field(default_factory=list)
103
+ equipment_usage_ids: list[str] = Field(default_factory=list)
104
+ area_room_usage_ids: list[str] = Field(default_factory=list)
105
+ yield_reconciliation_record_ids: list[str] = Field(default_factory=list)
106
+ cpp_cqa_registry_ids: list[str] = Field(default_factory=list)
107
+ deviation_ids: list[str] = Field(default_factory=list)
108
+ change_control_ids: list[str] = Field(default_factory=list)
109
+ evidence_document_ids: list[str] = Field(default_factory=list)
110
+
111
+ executed_by: Optional[str] = None
112
+ executed_at: Optional[datetime] = None
113
+ reviewed_by: Optional[str] = None
114
+ reviewed_at: Optional[datetime] = None
115
+ approved_by: Optional[str] = None
116
+ approved_at: Optional[datetime] = None
117
+ signature_ids: list[str] = Field(default_factory=list)
118
+ audit_event_ids: list[str] = Field(default_factory=list)
119
+ metadata: dict[str, Any] = Field(default_factory=dict)
120
+
121
+ created_by: Optional[str] = None
122
+ created_at: datetime = Field(default_factory=utc_now)
123
+ updated_at: datetime = Field(default_factory=utc_now)
124
+
125
+ @model_validator(mode="after")
126
+ def normalize_and_validate(self) -> "ExecutedBatchManufacturingRecord":
127
+ self.generated_at = ensure_utc(self.generated_at) or utc_now()
128
+ self.executed_at = ensure_utc(self.executed_at)
129
+ self.reviewed_at = ensure_utc(self.reviewed_at)
130
+ self.approved_at = ensure_utc(self.approved_at)
131
+ self.created_at = ensure_utc(self.created_at) or utc_now()
132
+ self.updated_at = ensure_utc(self.updated_at) or utc_now()
133
+
134
+ if self.status in {"Completed", "Under QA Review", "Approved"}:
135
+ if not self.generated_from_approved_template:
136
+ raise ValueError("executed BMR records must be generated from an approved MBMR/BMR template.")
137
+ if not self.sections:
138
+ raise ValueError("completed executed BMR records must include executed sections.")
139
+ if not self.batch_step_execution_ids:
140
+ raise ValueError("completed executed BMR records must include batch_step_execution_ids.")
141
+ if not self.evidence_document_ids:
142
+ raise ValueError("completed executed BMR records must include evidence_document_ids.")
143
+ if not self.executed_by or not self.executed_at:
144
+ raise ValueError("completed executed BMR records must include executed_by and executed_at.")
145
+ missing_requirements, missing_records = required_cleaning_coverage(self.metadata, self.cleaning_record_ids)
146
+ if missing_requirements:
147
+ raise ValueError(f"executed BMR records missing required cleaning coverage: {', '.join(missing_requirements)}.")
148
+ if missing_records:
149
+ raise ValueError(f"executed BMR records reference cleaning records not attached to BMR package: {', '.join(missing_records)}.")
150
+ missing_equipment_usage = missing_required_equipment_usage(self.metadata, self.equipment_usage_ids)
151
+ if missing_equipment_usage:
152
+ raise ValueError(f"executed BMR records missing required regulated equipment usage: {', '.join(missing_equipment_usage)}.")
153
+ incomplete = [section.title for section in self.sections if section.status not in {"Completed", "Skipped"}]
154
+ if incomplete:
155
+ raise ValueError(f"completed executed BMR records have incomplete sections: {', '.join(incomplete)}.")
156
+ unbound_sections = [
157
+ section.title
158
+ for section in self.sections
159
+ if section.status == "Completed" and (not section.report_template_ids or not section.report_template_section_ids)
160
+ ]
161
+ if unbound_sections:
162
+ raise ValueError(f"completed executed BMR sections missing report template binding: {', '.join(unbound_sections)}.")
163
+ if self.status in {"Under QA Review", "Approved"}:
164
+ if not self.reviewed_by or not self.reviewed_at:
165
+ raise ValueError("reviewed/approved executed BMR records must include reviewed_by and reviewed_at.")
166
+ if self.status == "Approved":
167
+ if not self.approved_by or not self.approved_at:
168
+ raise ValueError("approved executed BMR records must include approved_by and approved_at.")
169
+ if not self.signature_ids:
170
+ raise ValueError("approved executed BMR records must include signature_ids.")
171
+ return self
172
+
173
+
174
+ class ExecutedBmrRecordCreate(ExecutedBatchManufacturingRecord):
175
+ pass
176
+
177
+
178
+ class ExecutedBmrRecordUpdate(BaseModel):
179
+ status: Optional[ExecutedBmrStatus] = None
180
+ sections: Optional[list[ExecutedBmrSection]] = None
181
+ batch_step_execution_ids: Optional[list[str]] = None
182
+ dispense_weighing_record_ids: Optional[list[str]] = None
183
+ cleaning_record_ids: Optional[list[str]] = None
184
+ equipment_usage_ids: Optional[list[str]] = None
185
+ area_room_usage_ids: Optional[list[str]] = None
186
+ yield_reconciliation_record_ids: Optional[list[str]] = None
187
+ cpp_cqa_registry_ids: Optional[list[str]] = None
188
+ deviation_ids: Optional[list[str]] = None
189
+ change_control_ids: Optional[list[str]] = None
190
+ evidence_document_ids: Optional[list[str]] = None
191
+ executed_by: Optional[str] = None
192
+ executed_at: Optional[datetime] = None
193
+ reviewed_by: Optional[str] = None
194
+ reviewed_at: Optional[datetime] = None
195
+ approved_by: Optional[str] = None
196
+ approved_at: Optional[datetime] = None
197
+ signature_ids: Optional[list[str]] = None
198
+ audit_event_ids: Optional[list[str]] = None
199
+ metadata: Optional[dict[str, Any]] = None
200
+ updated_at: datetime = Field(default_factory=utc_now)
201
+
202
+ @model_validator(mode="after")
203
+ def normalize_datetimes(self) -> "ExecutedBmrRecordUpdate":
204
+ self.executed_at = ensure_utc(self.executed_at)
205
+ self.reviewed_at = ensure_utc(self.reviewed_at)
206
+ self.approved_at = ensure_utc(self.approved_at)
207
+ self.updated_at = ensure_utc(self.updated_at) or utc_now()
208
+ return self
209
+
210
+
211
+ class ExecutedBmrRecordResponse(ExecutedBatchManufacturingRecord):
212
+ class Config:
213
+ from_attributes = True
214
+
215
+
216
+ class PaginatedExecutedBmrRecordResponse(BaseModel):
217
+ total: int
218
+ page: int
219
+ page_size: int
220
+ results: list[ExecutedBmrRecordResponse]
@@ -0,0 +1,220 @@
1
+ from datetime import datetime, timezone
2
+ from typing import Any, Literal, Optional
3
+
4
+ from pydantic import BaseModel, Field, model_validator
5
+
6
+
7
+ ExecutedBprStatus = Literal["Draft", "In Progress", "Completed", "Under QA Review", "Approved", "Rejected", "Voided"]
8
+ ExecutedBprStepStatus = Literal["Pending", "In Progress", "Completed", "Skipped", "Rejected"]
9
+
10
+
11
+ def utc_now() -> datetime:
12
+ return datetime.now(timezone.utc)
13
+
14
+
15
+ def ensure_utc(value: Optional[datetime]) -> Optional[datetime]:
16
+ if value is None:
17
+ return None
18
+ if value.tzinfo is None:
19
+ return value.replace(tzinfo=timezone.utc)
20
+ return value.astimezone(timezone.utc)
21
+
22
+
23
+ def required_cleaning_coverage(metadata: dict[str, Any], cleaning_record_ids: list[str]) -> tuple[list[str], list[str]]:
24
+ required = [str(item) for item in metadata.get("required_cleaning_requirement_ids") or [] if item]
25
+ coverage = metadata.get("cleaning_requirement_record_map") if isinstance(metadata.get("cleaning_requirement_record_map"), dict) else {}
26
+ missing = [requirement_id for requirement_id in required if not coverage.get(requirement_id)]
27
+ referenced_records = {str(value) for value in coverage.values() if value}
28
+ missing_records = sorted(referenced_records.difference(set(cleaning_record_ids)))
29
+ return missing, missing_records
30
+
31
+
32
+ def missing_required_equipment_usage(metadata: dict[str, Any], equipment_usage_ids: list[str]) -> list[str]:
33
+ required = {str(item) for item in metadata.get("required_equipment_usage_ids") or [] if item}
34
+ attached = {str(item) for item in equipment_usage_ids if item}
35
+ return sorted(required.difference(attached))
36
+
37
+
38
+ class ExecutedBprStep(BaseModel):
39
+ step_execution_id: str = Field(..., min_length=1)
40
+ template_step_id: str = Field(..., min_length=1)
41
+ sequence: int = Field(..., ge=1)
42
+ title: str = Field(..., min_length=1)
43
+ process_step_id: Optional[str] = None
44
+ stage_id: Optional[str] = None
45
+ workstation_id: Optional[str] = None
46
+ status: ExecutedBprStepStatus = "Pending"
47
+ started_at: Optional[datetime] = None
48
+ completed_at: Optional[datetime] = None
49
+ performed_by: Optional[str] = None
50
+ verified_by: Optional[str] = None
51
+ actual_values: dict[str, Any] = Field(default_factory=dict)
52
+ packaging_component_lot_ids: list[str] = Field(default_factory=list)
53
+ reconciliation: dict[str, Any] = Field(default_factory=dict)
54
+ executed_instruction_evidence_ids: list[str] = Field(default_factory=list)
55
+ evidence_document_ids: list[str] = Field(default_factory=list)
56
+ report_template_ids: list[str] = Field(default_factory=list)
57
+ report_template_section_ids: list[str] = Field(default_factory=list)
58
+ signature_ids: list[str] = Field(default_factory=list)
59
+ comments: Optional[str] = None
60
+
61
+ @model_validator(mode="after")
62
+ def normalize_and_validate(self) -> "ExecutedBprStep":
63
+ self.started_at = ensure_utc(self.started_at)
64
+ self.completed_at = ensure_utc(self.completed_at)
65
+ if self.completed_at and self.started_at and self.completed_at < self.started_at:
66
+ raise ValueError("completed_at cannot be before started_at for an executed BPR step.")
67
+ if self.status == "Completed":
68
+ if not self.completed_at:
69
+ raise ValueError("completed executed BPR steps must include completed_at.")
70
+ if not self.performed_by:
71
+ raise ValueError("completed executed BPR steps must include performed_by.")
72
+ if not self.signature_ids:
73
+ raise ValueError("completed executed BPR steps must include signature_ids.")
74
+ return self
75
+
76
+
77
+ class ExecutedBatchPackagingRecord(BaseModel):
78
+ executed_bpr_record_id: str = Field(..., min_length=1)
79
+ executed_bpr_document_id: str = Field(..., min_length=1)
80
+ batch_execution_record_id: str = Field(..., min_length=1)
81
+ batch_id: str = Field(..., min_length=1)
82
+ batch_number: Optional[str] = None
83
+
84
+ packing_instruction_id: str = Field(..., min_length=1)
85
+ instruction_template_id: str = Field(..., min_length=1)
86
+ bpr_template_document_id: str = Field(..., min_length=1)
87
+ template_revision: Optional[str] = None
88
+ generated_from_approved_instruction: bool = False
89
+ generated_at: datetime = Field(default_factory=utc_now)
90
+
91
+ process_definition_id: str = Field(..., min_length=1)
92
+ bpr_process_definition_id: str = Field(..., min_length=1)
93
+ bom_id: str = Field(..., min_length=1)
94
+ product_id: Optional[str] = None
95
+ plant_id: Optional[str] = None
96
+ line_id: Optional[str] = None
97
+
98
+ status: ExecutedBprStatus = "Draft"
99
+ steps: list[ExecutedBprStep] = Field(default_factory=list)
100
+ packaging_component_lot_ids: list[str] = Field(default_factory=list)
101
+ line_clearance_ids: list[str] = Field(default_factory=list)
102
+ serialization_lot_ids: list[str] = Field(default_factory=list)
103
+ yield_reconciliation_record_ids: list[str] = Field(default_factory=list)
104
+ cleaning_record_ids: list[str] = Field(default_factory=list)
105
+ equipment_usage_ids: list[str] = Field(default_factory=list)
106
+ area_room_usage_ids: list[str] = Field(default_factory=list)
107
+ cpp_cqa_registry_ids: list[str] = Field(default_factory=list)
108
+ deviation_ids: list[str] = Field(default_factory=list)
109
+ change_control_ids: list[str] = Field(default_factory=list)
110
+ evidence_document_ids: list[str] = Field(default_factory=list)
111
+
112
+ executed_by: Optional[str] = None
113
+ executed_at: Optional[datetime] = None
114
+ reviewed_by: Optional[str] = None
115
+ reviewed_at: Optional[datetime] = None
116
+ approved_by: Optional[str] = None
117
+ approved_at: Optional[datetime] = None
118
+ signature_ids: list[str] = Field(default_factory=list)
119
+ audit_event_ids: list[str] = Field(default_factory=list)
120
+ metadata: dict[str, Any] = Field(default_factory=dict)
121
+
122
+ created_by: Optional[str] = None
123
+ created_at: datetime = Field(default_factory=utc_now)
124
+ updated_at: datetime = Field(default_factory=utc_now)
125
+
126
+ @model_validator(mode="after")
127
+ def normalize_and_validate(self) -> "ExecutedBatchPackagingRecord":
128
+ self.generated_at = ensure_utc(self.generated_at) or utc_now()
129
+ self.executed_at = ensure_utc(self.executed_at)
130
+ self.reviewed_at = ensure_utc(self.reviewed_at)
131
+ self.approved_at = ensure_utc(self.approved_at)
132
+ self.created_at = ensure_utc(self.created_at) or utc_now()
133
+ self.updated_at = ensure_utc(self.updated_at) or utc_now()
134
+
135
+ if self.status in {"Completed", "Under QA Review", "Approved"}:
136
+ if not self.generated_from_approved_instruction:
137
+ raise ValueError("executed BPR records must be generated from an approved packing instruction.")
138
+ if not self.steps:
139
+ raise ValueError("completed executed BPR records must include executed packaging steps.")
140
+ if not self.evidence_document_ids:
141
+ raise ValueError("completed executed BPR records must include evidence_document_ids.")
142
+ if not self.executed_by or not self.executed_at:
143
+ raise ValueError("completed executed BPR records must include executed_by and executed_at.")
144
+ missing_requirements, missing_records = required_cleaning_coverage(self.metadata, self.cleaning_record_ids)
145
+ if missing_requirements:
146
+ raise ValueError(f"executed BPR records missing required cleaning coverage: {', '.join(missing_requirements)}.")
147
+ if missing_records:
148
+ raise ValueError(f"executed BPR records reference cleaning records not attached to BPR package: {', '.join(missing_records)}.")
149
+ missing_equipment_usage = missing_required_equipment_usage(self.metadata, self.equipment_usage_ids)
150
+ if missing_equipment_usage:
151
+ raise ValueError(f"executed BPR records missing required regulated equipment usage: {', '.join(missing_equipment_usage)}.")
152
+ incomplete = [step.title for step in self.steps if step.status not in {"Completed", "Skipped"}]
153
+ if incomplete:
154
+ raise ValueError(f"completed executed BPR records have incomplete steps: {', '.join(incomplete)}.")
155
+ unbound_steps = [
156
+ step.title
157
+ for step in self.steps
158
+ if step.status == "Completed" and (not step.report_template_ids or not step.report_template_section_ids)
159
+ ]
160
+ if unbound_steps:
161
+ raise ValueError(f"completed executed BPR steps missing report template binding: {', '.join(unbound_steps)}.")
162
+ if self.status in {"Under QA Review", "Approved"}:
163
+ if not self.reviewed_by or not self.reviewed_at:
164
+ raise ValueError("reviewed/approved executed BPR records must include reviewed_by and reviewed_at.")
165
+ if self.status == "Approved":
166
+ if not self.approved_by or not self.approved_at:
167
+ raise ValueError("approved executed BPR records must include approved_by and approved_at.")
168
+ if not self.signature_ids:
169
+ raise ValueError("approved executed BPR records must include signature_ids.")
170
+ return self
171
+
172
+
173
+ class ExecutedBprRecordCreate(ExecutedBatchPackagingRecord):
174
+ pass
175
+
176
+
177
+ class ExecutedBprRecordUpdate(BaseModel):
178
+ status: Optional[ExecutedBprStatus] = None
179
+ steps: Optional[list[ExecutedBprStep]] = None
180
+ packaging_component_lot_ids: Optional[list[str]] = None
181
+ line_clearance_ids: Optional[list[str]] = None
182
+ serialization_lot_ids: Optional[list[str]] = None
183
+ yield_reconciliation_record_ids: Optional[list[str]] = None
184
+ cleaning_record_ids: Optional[list[str]] = None
185
+ equipment_usage_ids: Optional[list[str]] = None
186
+ area_room_usage_ids: Optional[list[str]] = None
187
+ cpp_cqa_registry_ids: Optional[list[str]] = None
188
+ deviation_ids: Optional[list[str]] = None
189
+ change_control_ids: Optional[list[str]] = None
190
+ evidence_document_ids: Optional[list[str]] = None
191
+ executed_by: Optional[str] = None
192
+ executed_at: Optional[datetime] = None
193
+ reviewed_by: Optional[str] = None
194
+ reviewed_at: Optional[datetime] = None
195
+ approved_by: Optional[str] = None
196
+ approved_at: Optional[datetime] = None
197
+ signature_ids: Optional[list[str]] = None
198
+ audit_event_ids: Optional[list[str]] = None
199
+ metadata: Optional[dict[str, Any]] = None
200
+ updated_at: datetime = Field(default_factory=utc_now)
201
+
202
+ @model_validator(mode="after")
203
+ def normalize_datetimes(self) -> "ExecutedBprRecordUpdate":
204
+ self.executed_at = ensure_utc(self.executed_at)
205
+ self.reviewed_at = ensure_utc(self.reviewed_at)
206
+ self.approved_at = ensure_utc(self.approved_at)
207
+ self.updated_at = ensure_utc(self.updated_at) or utc_now()
208
+ return self
209
+
210
+
211
+ class ExecutedBprRecordResponse(ExecutedBatchPackagingRecord):
212
+ class Config:
213
+ from_attributes = True
214
+
215
+
216
+ class PaginatedExecutedBprRecordResponse(BaseModel):
217
+ total: int
218
+ page: int
219
+ page_size: int
220
+ results: list[ExecutedBprRecordResponse]
@@ -0,0 +1,128 @@
1
+ from datetime import datetime, timezone
2
+ from typing import Any, Literal, Optional
3
+
4
+ from pydantic import BaseModel, Field, model_validator
5
+
6
+
7
+ ExecutedInstructionEvidenceStatus = Literal["Draft", "Captured", "Verified", "Rejected", "Voided"]
8
+ InstructionSourceRecordType = Literal["BMR", "BPR", "Cleaning", "Equipment", "Area", "Other"]
9
+
10
+
11
+ def utc_now() -> datetime:
12
+ return datetime.now(timezone.utc)
13
+
14
+
15
+ def ensure_utc(value: Optional[datetime]) -> Optional[datetime]:
16
+ if value is None:
17
+ return None
18
+ if value.tzinfo is None:
19
+ return value.replace(tzinfo=timezone.utc)
20
+ return value.astimezone(timezone.utc)
21
+
22
+
23
+ class ExecutedInstructionEvidence(BaseModel):
24
+ executed_instruction_evidence_id: str = Field(..., min_length=1)
25
+ batch_step_execution_id: Optional[str] = None
26
+ executed_bpr_step_id: Optional[str] = None
27
+ batch_execution_record_id: str = Field(..., min_length=1)
28
+ batch_id: str = Field(..., min_length=1)
29
+
30
+ instruction_template_id: str = Field(..., min_length=1)
31
+ instruction_step_id: str = Field(..., min_length=1)
32
+ instruction_revision: Optional[str] = None
33
+ instruction_text_snapshot: str = Field(..., min_length=1)
34
+ acceptance_criteria_snapshot: Optional[str] = None
35
+
36
+ source_record_type: InstructionSourceRecordType = "BMR"
37
+ source_record_id: Optional[str] = None
38
+ source_document_id: Optional[str] = None
39
+ source_section_id: Optional[str] = None
40
+
41
+ process_definition_id: str = Field(..., min_length=1)
42
+ process_step_id: str = Field(..., min_length=1)
43
+ stage_id: Optional[str] = None
44
+ workstation_id: Optional[str] = None
45
+ equipment_ids: list[str] = Field(default_factory=list)
46
+
47
+ status: ExecutedInstructionEvidenceStatus = "Draft"
48
+ performed_by: Optional[str] = None
49
+ performed_at: Optional[datetime] = None
50
+ verified_by: Optional[str] = None
51
+ verified_at: Optional[datetime] = None
52
+ actual_values: dict[str, Any] = Field(default_factory=dict)
53
+ exception_notes: Optional[str] = None
54
+ deviation_id: Optional[str] = None
55
+ evidence_document_ids: list[str] = Field(default_factory=list)
56
+ signature_ids: list[str] = Field(default_factory=list)
57
+ audit_event_ids: list[str] = Field(default_factory=list)
58
+ metadata: dict[str, Any] = Field(default_factory=dict)
59
+
60
+ created_by: Optional[str] = None
61
+ created_at: datetime = Field(default_factory=utc_now)
62
+ updated_at: datetime = Field(default_factory=utc_now)
63
+
64
+ @model_validator(mode="after")
65
+ def normalize_and_validate(self) -> "ExecutedInstructionEvidence":
66
+ self.performed_at = ensure_utc(self.performed_at)
67
+ self.verified_at = ensure_utc(self.verified_at)
68
+ self.created_at = ensure_utc(self.created_at) or utc_now()
69
+ self.updated_at = ensure_utc(self.updated_at) or utc_now()
70
+ if not self.batch_step_execution_id and not self.executed_bpr_step_id:
71
+ raise ValueError("executed instruction evidence must include batch_step_execution_id or executed_bpr_step_id.")
72
+ if self.verified_at and self.performed_at and self.verified_at < self.performed_at:
73
+ raise ValueError("verified_at cannot be before performed_at for executed instruction evidence.")
74
+ if self.status in {"Captured", "Verified"}:
75
+ if not self.source_record_id or not self.source_document_id:
76
+ raise ValueError("captured executed instruction evidence must include source_record_id and source_document_id.")
77
+ if not self.performed_by or not self.performed_at:
78
+ raise ValueError("captured executed instruction evidence must include performed_by and performed_at.")
79
+ if not self.actual_values:
80
+ raise ValueError("captured executed instruction evidence must include actual_values.")
81
+ if not self.evidence_document_ids:
82
+ raise ValueError("captured executed instruction evidence must include evidence_document_ids.")
83
+ if not self.signature_ids:
84
+ raise ValueError("captured executed instruction evidence must include signature_ids.")
85
+ if self.status == "Verified" and (not self.verified_by or not self.verified_at):
86
+ raise ValueError("verified executed instruction evidence must include verified_by and verified_at.")
87
+ if self.status == "Rejected" and not (self.exception_notes or self.deviation_id):
88
+ raise ValueError("rejected executed instruction evidence must include exception_notes or deviation_id.")
89
+ return self
90
+
91
+
92
+ class ExecutedInstructionEvidenceCreate(ExecutedInstructionEvidence):
93
+ pass
94
+
95
+
96
+ class ExecutedInstructionEvidenceUpdate(BaseModel):
97
+ status: Optional[ExecutedInstructionEvidenceStatus] = None
98
+ performed_by: Optional[str] = None
99
+ performed_at: Optional[datetime] = None
100
+ verified_by: Optional[str] = None
101
+ verified_at: Optional[datetime] = None
102
+ actual_values: Optional[dict[str, Any]] = None
103
+ exception_notes: Optional[str] = None
104
+ deviation_id: Optional[str] = None
105
+ evidence_document_ids: Optional[list[str]] = None
106
+ signature_ids: Optional[list[str]] = None
107
+ audit_event_ids: Optional[list[str]] = None
108
+ metadata: Optional[dict[str, Any]] = None
109
+ updated_at: datetime = Field(default_factory=utc_now)
110
+
111
+ @model_validator(mode="after")
112
+ def normalize_datetimes(self) -> "ExecutedInstructionEvidenceUpdate":
113
+ self.performed_at = ensure_utc(self.performed_at)
114
+ self.verified_at = ensure_utc(self.verified_at)
115
+ self.updated_at = ensure_utc(self.updated_at) or utc_now()
116
+ return self
117
+
118
+
119
+ class ExecutedInstructionEvidenceResponse(ExecutedInstructionEvidence):
120
+ class Config:
121
+ from_attributes = True
122
+
123
+
124
+ class PaginatedExecutedInstructionEvidenceResponse(BaseModel):
125
+ total: int
126
+ page: int
127
+ page_size: int
128
+ results: list[ExecutedInstructionEvidenceResponse]