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.
- monkeybrain_runtime-1.0.0.dist-info/METADATA +76 -0
- monkeybrain_runtime-1.0.0.dist-info/RECORD +838 -0
- monkeybrain_runtime-1.0.0.dist-info/WHEEL +5 -0
- monkeybrain_runtime-1.0.0.dist-info/entry_points.txt +3 -0
- monkeybrain_runtime-1.0.0.dist-info/top_level.txt +2 -0
- services/__init__.py +8 -0
- services/agentos/__init__.py +0 -0
- services/agentos/main.py +1 -0
- services/assets/helpers/__init__.py +12 -0
- services/assets/helpers/device.py +59 -0
- services/assets/helpers/equipment.py +179 -0
- services/assets/helpers/instruments.py +72 -0
- services/assets/helpers/machines.py +183 -0
- services/assets/helpers/materials.py +76 -0
- services/assets/helpers/parts.py +116 -0
- services/assets/helpers/plc.py +134 -0
- services/assets/helpers/tags.py +108 -0
- services/assets/helpers/tools.py +101 -0
- services/assets/main.py +75 -0
- services/assets/models/__init__.py +12 -0
- services/assets/models/device.py +79 -0
- services/assets/models/equipment.py +222 -0
- services/assets/models/instruments.py +85 -0
- services/assets/models/machines.py +230 -0
- services/assets/models/material.py +266 -0
- services/assets/models/parts.py +96 -0
- services/assets/models/plc.py +264 -0
- services/assets/models/tags.py +76 -0
- services/assets/models/tools.py +179 -0
- services/assets/routers/__init__.py +12 -0
- services/assets/routers/classes.py +65 -0
- services/assets/routers/device.py +86 -0
- services/assets/routers/equipment.py +145 -0
- services/assets/routers/families.py +61 -0
- services/assets/routers/instruments.py +70 -0
- services/assets/routers/machines.py +136 -0
- services/assets/routers/materials.py +105 -0
- services/assets/routers/parts.py +130 -0
- services/assets/routers/plc.py +94 -0
- services/assets/routers/subclasses.py +68 -0
- services/assets/routers/tags.py +138 -0
- services/assets/routers/tools.py +113 -0
- services/auth/helpers/__init__.py +13 -0
- services/auth/helpers/approval_decisions.py +261 -0
- services/auth/helpers/audit_elasticsearch_sync.py +350 -0
- services/auth/helpers/departments.py +53 -0
- services/auth/helpers/graph_store.py +848 -0
- services/auth/helpers/influx_store.py +280 -0
- services/auth/helpers/me.py +33 -0
- services/auth/helpers/nats_consumer.py +618 -0
- services/auth/helpers/nats_store.py +242 -0
- services/auth/helpers/permissions.py +62 -0
- services/auth/helpers/roles.py +87 -0
- services/auth/helpers/store.py +54 -0
- services/auth/helpers/team_members.py +155 -0
- services/auth/helpers/teams.py +87 -0
- services/auth/helpers/tokens.py +71 -0
- services/auth/helpers/users.py +119 -0
- services/auth/helpers/websocket_broadcast.py +41 -0
- services/auth/main.py +88 -0
- services/auth/models/__init__.py +12 -0
- services/auth/models/departments.py +55 -0
- services/auth/models/login.py +20 -0
- services/auth/models/permissions.py +61 -0
- services/auth/models/roles.py +53 -0
- services/auth/models/session.py +26 -0
- services/auth/models/teamMembers.py +59 -0
- services/auth/models/teams.py +56 -0
- services/auth/models/users.py +77 -0
- services/auth/routers/__init__.py +14 -0
- services/auth/routers/auth.py +3839 -0
- services/auth/routers/departments.py +84 -0
- services/auth/routers/integration_config.py +703 -0
- services/auth/routers/me.py +28 -0
- services/auth/routers/permissions.py +96 -0
- services/auth/routers/roles.py +139 -0
- services/auth/routers/session.py +224 -0
- services/auth/routers/team_members.py +152 -0
- services/auth/routers/teams.py +112 -0
- services/auth/routers/users.py +131 -0
- services/auth/routers/websocket_events.py +247 -0
- services/batch_execution/__init__.py +19 -0
- services/batch_execution/pipeline_triggers/__init__.py +53 -0
- services/batch_execution/pipeline_triggers/pipeline_parameter_adjuster.py +440 -0
- services/batch_execution/pipeline_triggers/pipeline_trigger_engine.py +445 -0
- services/batch_execution/pipeline_triggers/re_evaluation_queue.py +341 -0
- services/batch_execution/pipeline_triggers/test_phase3_implementation.py +553 -0
- services/batch_execution/pipeline_triggers/workflow_reevaluator.py +367 -0
- services/batch_execution/smoke_test_e2e_feedback_loop.py +704 -0
- services/batch_execution/workflow_executor.py +478 -0
- services/changeover/helpers/__init__.py +11 -0
- services/changeover/helpers/changeover.py +87 -0
- services/changeover/helpers/changeover_common.py +55 -0
- services/changeover/helpers/changeover_events.py +66 -0
- services/changeover/helpers/changeover_kpis.py +33 -0
- services/changeover/helpers/changeover_matrix.py +60 -0
- services/changeover/helpers/changeover_procedures.py +164 -0
- services/changeover/helpers/changeover_windows.py +96 -0
- services/changeover/main.py +52 -0
- services/changeover/models/__init__.py +11 -0
- services/changeover/models/changeover.py +73 -0
- services/changeover/models/changeover_events.py +142 -0
- services/changeover/models/changeover_kpis.py +75 -0
- services/changeover/models/changeover_matrix.py +63 -0
- services/changeover/models/changeover_procedures.py +108 -0
- services/changeover/models/changeover_tasks.py +87 -0
- services/changeover/models/changeover_windows.py +72 -0
- services/changeover/routers/__init__.py +9 -0
- services/changeover/routers/changeover_events.py +127 -0
- services/changeover/routers/changeover_kpis.py +80 -0
- services/changeover/routers/changeover_matrix.py +80 -0
- services/changeover/routers/changeover_procedures.py +118 -0
- services/changeover/routers/changeover_windows.py +98 -0
- services/common/__init__.py +2 -0
- services/common/approval_chains.py +648 -0
- services/common/auth.py +56 -0
- services/common/cdc.py +52 -0
- services/common/compat.py +217 -0
- services/common/compliance.py +562 -0
- services/common/config.py +134 -0
- services/common/cors.py +17 -0
- services/common/data_transformation.py +195 -0
- services/common/db.py +577 -0
- services/common/embeddings.py +97 -0
- services/common/event_reducers.py +194 -0
- services/common/event_types.py +51 -0
- services/common/integration_ingestion.py +169 -0
- services/common/logging.py +204 -0
- services/common/models/__init__.py +2 -0
- services/common/models/databricks.py +25 -0
- services/common/models/enums.py +64 -0
- services/common/module_control.py +422 -0
- services/common/mongo_cdc_watcher.py +106 -0
- services/common/n8n_auth.py +22 -0
- services/common/neo4j_mirror.py +1087 -0
- services/common/ontology_registry.py +110 -0
- services/common/reasoning_traces.py +52 -0
- services/common/supply_chain_cdc.py +555 -0
- services/common/tracing.py +159 -0
- services/common/utils.py +30 -0
- services/customers/helpers/__init__.py +8 -0
- services/customers/helpers/customer_details.py +64 -0
- services/customers/helpers/customer_metadata.py +64 -0
- services/customers/helpers/customer_order_metrics.py +67 -0
- services/customers/helpers/customer_payment_data.py +67 -0
- services/customers/main.py +50 -0
- services/customers/models/__init__.py +8 -0
- services/customers/models/customer_details.py +42 -0
- services/customers/models/customer_metadata.py +97 -0
- services/customers/models/customer_order_metrics.py +86 -0
- services/customers/models/customer_payment_data.py +60 -0
- services/customers/routers/__init__.py +8 -0
- services/customers/routers/customer_details.py +88 -0
- services/customers/routers/customer_metadata.py +88 -0
- services/customers/routers/customer_order_metrics.py +88 -0
- services/customers/routers/customer_payment_data.py +88 -0
- services/documents/__init__.py +1 -0
- services/documents/helpers/__init__.py +6 -0
- services/documents/helpers/document_metadata.py +569 -0
- services/documents/helpers/document_workflows.py +215 -0
- services/documents/helpers/report_templates.py +113 -0
- services/documents/main.py +49 -0
- services/documents/models/__init__.py +6 -0
- services/documents/models/document_metadata.py +215 -0
- services/documents/models/document_workflows.py +136 -0
- services/documents/models/report_templates.py +132 -0
- services/documents/routers/__init__.py +6 -0
- services/documents/routers/document_metadata.py +654 -0
- services/documents/routers/document_workflows.py +146 -0
- services/documents/routers/report_templates.py +86 -0
- services/events/helpers/__init__.py +5 -0
- services/events/helpers/events.py +394 -0
- services/events/main.py +40 -0
- services/events/models/__init__.py +5 -0
- services/events/models/events.py +50 -0
- services/events/routers/__init__.py +6 -0
- services/events/routers/count_events.py +109 -0
- services/events/routers/events.py +75 -0
- services/events/seed_events.py +196 -0
- services/facilities/helpers/__init__.py +8 -0
- services/facilities/helpers/lines.py +74 -0
- services/facilities/helpers/locations.py +231 -0
- services/facilities/helpers/plants.py +59 -0
- services/facilities/helpers/stages.py +110 -0
- services/facilities/helpers/workstation.py +213 -0
- services/facilities/main.py +60 -0
- services/facilities/models/__init__.py +10 -0
- services/facilities/models/industrialLine.py +72 -0
- services/facilities/models/industrialPlant.py +164 -0
- services/facilities/models/locations.py +74 -0
- services/facilities/models/stages.py +92 -0
- services/facilities/models/worker.py +73 -0
- services/facilities/models/workstation.py +117 -0
- services/facilities/models/workstation_live_state.py +59 -0
- services/facilities/routers/__init__.py +8 -0
- services/facilities/routers/bays.py +81 -0
- services/facilities/routers/buildings.py +92 -0
- services/facilities/routers/floors.py +81 -0
- services/facilities/routers/lines.py +154 -0
- services/facilities/routers/locations.py +208 -0
- services/facilities/routers/plant.py +203 -0
- services/facilities/routers/rooms.py +81 -0
- services/facilities/routers/stages.py +152 -0
- services/facilities/routers/workstation.py +173 -0
- services/file/backup.py +71 -0
- services/file/main.py +45 -0
- services/file/recieve.py +54 -0
- services/file/send.py +55 -0
- services/file/src/core/config.py +90 -0
- services/file/src/core/keycloak.py +152 -0
- services/file/src/core/logging_config.py +9 -0
- services/file/src/core/security.py +33 -0
- services/file/src/helpers/cad_conversion.py +331 -0
- services/file/src/helpers/helpers.py +825 -0
- services/file/src/routes/cad_conversion.py +26 -0
- services/file/src/routes/files.py +136 -0
- services/file/src/routes/presigned.py +154 -0
- services/file/src/services/websocket.py +293 -0
- services/floor_layout/helpers/__init__.py +8 -0
- services/floor_layout/helpers/bays.py +92 -0
- services/floor_layout/helpers/buildings.py +54 -0
- services/floor_layout/helpers/floors.py +65 -0
- services/floor_layout/helpers/rooms.py +76 -0
- services/floor_layout/main.py +52 -0
- services/floor_layout/models/__init__.py +8 -0
- services/floor_layout/models/bays.py +65 -0
- services/floor_layout/models/buildings.py +52 -0
- services/floor_layout/models/floors.py +45 -0
- services/floor_layout/models/rooms.py +61 -0
- services/floor_layout/routers/__init__.py +9 -0
- services/floor_layout/routers/bays.py +143 -0
- services/floor_layout/routers/buildings.py +116 -0
- services/floor_layout/routers/floors.py +89 -0
- services/floor_layout/routers/locations.py +80 -0
- services/floor_layout/routers/rooms.py +134 -0
- services/inventory/helpers/__init__.py +13 -0
- services/inventory/helpers/cycle_counts.py +124 -0
- services/inventory/helpers/inventory_allocations.py +134 -0
- services/inventory/helpers/inventory_item_counts.py +114 -0
- services/inventory/helpers/inventory_item_quantities.py +114 -0
- services/inventory/helpers/inventory_items.py +103 -0
- services/inventory/helpers/inventory_stage_outputs.py +134 -0
- services/inventory/helpers/inventory_transactions.py +112 -0
- services/inventory/helpers/stock_adjustment_requests.py +101 -0
- services/inventory/helpers/warehouse_cycle_counts.py +133 -0
- services/inventory/helpers/warehouse_locations.py +213 -0
- services/inventory/helpers/warehouse_regulated_records.py +123 -0
- services/inventory/main.py +62 -0
- services/inventory/models/__init__.py +17 -0
- services/inventory/models/cycle_counts.py +99 -0
- services/inventory/models/inventory_allocations.py +121 -0
- services/inventory/models/inventory_common.py +65 -0
- services/inventory/models/inventory_enums.py +21 -0
- services/inventory/models/inventory_item_count.py +65 -0
- services/inventory/models/inventory_item_quantity.py +82 -0
- services/inventory/models/inventory_items.py +168 -0
- services/inventory/models/inventory_responses.py +44 -0
- services/inventory/models/inventory_stage_outputs.py +96 -0
- services/inventory/models/inventory_state.py +15 -0
- services/inventory/models/inventory_transactions.py +80 -0
- services/inventory/models/stock_adjustment_requests.py +109 -0
- services/inventory/models/warehouse_cycle_counts.py +119 -0
- services/inventory/models/warehouse_location_models.py +708 -0
- services/inventory/models/warehouse_regulated_records.py +358 -0
- services/inventory/routers/__init__.py +13 -0
- services/inventory/routers/cycle_counts.py +106 -0
- services/inventory/routers/inventory_allocations.py +125 -0
- services/inventory/routers/inventory_item_counts.py +105 -0
- services/inventory/routers/inventory_item_quantities.py +105 -0
- services/inventory/routers/inventory_items.py +109 -0
- services/inventory/routers/inventory_stage_outputs.py +122 -0
- services/inventory/routers/inventory_transactions.py +96 -0
- services/inventory/routers/stock_adjustment_requests.py +124 -0
- services/inventory/routers/warehouse_cycle_counts.py +124 -0
- services/inventory/routers/warehouse_locations.py +426 -0
- services/inventory/routers/warehouse_regulated_records.py +273 -0
- services/iot/helpers/__init__.py +8 -0
- services/iot/helpers/ble_device.py +87 -0
- services/iot/helpers/mqtt_bridge.py +115 -0
- services/iot/helpers/sensor_readings.py +63 -0
- services/iot/helpers/sensors.py +77 -0
- services/iot/helpers/servers.py +72 -0
- services/iot/helpers/uwb_device.py +95 -0
- services/iot/main.py +53 -0
- services/iot/models/__init__.py +8 -0
- services/iot/models/ble_device.py +118 -0
- services/iot/models/sensors.py +256 -0
- services/iot/models/servers.py +206 -0
- services/iot/models/uwb_device.py +106 -0
- services/iot/routers/__init__.py +8 -0
- services/iot/routers/ble_device.py +110 -0
- services/iot/routers/sensors.py +144 -0
- services/iot/routers/servers.py +141 -0
- services/iot/routers/uwb_device.py +148 -0
- services/module_control/__init__.py +1 -0
- services/module_control/helpers/__init__.py +1 -0
- services/module_control/helpers/integration_config.py +243 -0
- services/module_control/helpers/security.py +104 -0
- services/module_control/main.py +44 -0
- services/module_control/models/__init__.py +1 -0
- services/module_control/models/module_control.py +65 -0
- services/module_control/routers/__init__.py +1 -0
- services/module_control/routers/module_control.py +219 -0
- services/orders/helpers/__init__.py +11 -0
- services/orders/helpers/invoices.py +123 -0
- services/orders/helpers/order_customer_metrics.py +61 -0
- services/orders/helpers/order_details.py +71 -0
- services/orders/helpers/order_metadata.py +61 -0
- services/orders/helpers/order_payment_metadata.py +74 -0
- services/orders/helpers/orders.py +119 -0
- services/orders/helpers/sales_orders.py +136 -0
- services/orders/main.py +56 -0
- services/orders/models/__init__.py +11 -0
- services/orders/models/invoices.py +415 -0
- services/orders/models/order_customer_metrics.py +78 -0
- services/orders/models/order_details.py +46 -0
- services/orders/models/order_metadata.py +60 -0
- services/orders/models/order_payment_metadata.py +63 -0
- services/orders/models/orders.py +64 -0
- services/orders/models/sales_orders.py +130 -0
- services/orders/routers/__init__.py +11 -0
- services/orders/routers/invoices.py +111 -0
- services/orders/routers/order_customer_metrics.py +87 -0
- services/orders/routers/order_details.py +87 -0
- services/orders/routers/order_metadata.py +87 -0
- services/orders/routers/order_payment_metadata.py +87 -0
- services/orders/routers/orders.py +74 -0
- services/orders/routers/sales_orders.py +111 -0
- services/pm/helpers/__init__.py +14 -0
- services/pm/helpers/calendar_bookings.py +114 -0
- services/pm/helpers/calibration_point.py +110 -0
- services/pm/helpers/calibrations.py +196 -0
- services/pm/helpers/checklists.py +318 -0
- services/pm/helpers/cleaning.py +333 -0
- services/pm/helpers/downtime.py +376 -0
- services/pm/helpers/kanban_boards.py +186 -0
- services/pm/helpers/maintainance.py +177 -0
- services/pm/helpers/sop.py +1155 -0
- services/pm/helpers/sop_cdc.py +324 -0
- services/pm/helpers/weekly_schedules.py +79 -0
- services/pm/main.py +62 -0
- services/pm/models/__init__.py +14 -0
- services/pm/models/calendar_booking.py +82 -0
- services/pm/models/calibration_point.py +44 -0
- services/pm/models/calibrations.py +167 -0
- services/pm/models/checklists.py +117 -0
- services/pm/models/cleaning.py +203 -0
- services/pm/models/downtime.py +109 -0
- services/pm/models/kanban_board.py +178 -0
- services/pm/models/maintainanceLog.py +148 -0
- services/pm/models/sop.py +152 -0
- services/pm/models/weekly_schedule.py +91 -0
- services/pm/routers/__init__.py +14 -0
- services/pm/routers/calendar_bookings.py +143 -0
- services/pm/routers/calibration_point.py +94 -0
- services/pm/routers/calibrations.py +232 -0
- services/pm/routers/checklists.py +188 -0
- services/pm/routers/cleaning.py +127 -0
- services/pm/routers/downtime.py +143 -0
- services/pm/routers/kanban_boards.py +283 -0
- services/pm/routers/maintainance.py +241 -0
- services/pm/routers/sop.py +437 -0
- services/pm/routers/weekly_schedules.py +108 -0
- services/process_definitions/helpers/__init__.py +11 -0
- services/process_definitions/helpers/cpp_cqa_registry.py +120 -0
- services/process_definitions/helpers/mbmr_templates.py +107 -0
- services/process_definitions/helpers/packing_instructions.py +113 -0
- services/process_definitions/helpers/process_constraints.py +495 -0
- services/process_definitions/helpers/process_corrections.py +279 -0
- services/process_definitions/helpers/process_definition.py +996 -0
- services/process_definitions/helpers/process_node_catalog.py +786 -0
- services/process_definitions/helpers/process_post_checks.py +441 -0
- services/process_definitions/helpers/process_pre_checks.py +351 -0
- services/process_definitions/helpers/process_steps.py +220 -0
- services/process_definitions/main.py +71 -0
- services/process_definitions/models/__init__.py +13 -0
- services/process_definitions/models/cpp_cqa_registry.py +145 -0
- services/process_definitions/models/gxp_change_controls.py +38 -0
- services/process_definitions/models/gxp_risk_assessments.py +30 -0
- services/process_definitions/models/gxp_validation_evidence.py +33 -0
- services/process_definitions/models/mbmr_templates.py +173 -0
- services/process_definitions/models/packing_instructions.py +176 -0
- services/process_definitions/models/process_constraints.py +159 -0
- services/process_definitions/models/process_corrections.py +118 -0
- services/process_definitions/models/process_definition.py +685 -0
- services/process_definitions/models/process_definition_common.py +48 -0
- services/process_definitions/models/process_node_catalog.py +25 -0
- services/process_definitions/models/process_post_checks.py +171 -0
- services/process_definitions/models/process_pre_checks.py +168 -0
- services/process_definitions/models/process_steps.py +170 -0
- services/process_definitions/node_services/__init__.py +8 -0
- services/process_definitions/node_services/common.py +95 -0
- services/process_definitions/node_services/executor.py +499 -0
- services/process_definitions/node_services/flow_simulator.py +733 -0
- services/process_definitions/node_services/functions.py +193 -0
- services/process_definitions/node_services/messaging.py +44 -0
- services/process_definitions/node_services/models.py +221 -0
- services/process_definitions/node_services/network.py +161 -0
- services/process_definitions/node_services/parsers.py +87 -0
- services/process_definitions/node_services/sequence.py +95 -0
- services/process_definitions/node_services/storage.py +50 -0
- services/process_definitions/node_services/webhooks.py +52 -0
- services/process_definitions/routers/__init__.py +10 -0
- services/process_definitions/routers/cpp_cqa_registry.py +86 -0
- services/process_definitions/routers/mbmr_templates.py +84 -0
- services/process_definitions/routers/packing_instructions.py +84 -0
- services/process_definitions/routers/process_constraints.py +564 -0
- services/process_definitions/routers/process_corrections.py +343 -0
- services/process_definitions/routers/process_definition.py +992 -0
- services/process_definitions/routers/process_post_checks.py +529 -0
- services/process_definitions/routers/process_pre_checks.py +435 -0
- services/process_definitions/routers/process_steps.py +274 -0
- services/procurement/helpers/__init__.py +9 -0
- services/procurement/helpers/goods_receipts.py +240 -0
- services/procurement/helpers/purchase_order_shipping_information.py +85 -0
- services/procurement/helpers/purchase_orders.py +68 -0
- services/procurement/helpers/quality_control.py +235 -0
- services/procurement/helpers/sampling.py +404 -0
- services/procurement/main.py +52 -0
- services/procurement/models/__init__.py +9 -0
- services/procurement/models/goods_receipts.py +165 -0
- services/procurement/models/purchase_orders.py +54 -0
- services/procurement/models/quality_control.py +464 -0
- services/procurement/models/reinspection_records.py +28 -0
- services/procurement/models/sampling.py +262 -0
- services/procurement/models/shipping_information.py +51 -0
- services/procurement/routers/__init__.py +9 -0
- services/procurement/routers/goods_receipts.py +201 -0
- services/procurement/routers/purchase_orders.py +106 -0
- services/procurement/routers/quality_control.py +386 -0
- services/procurement/routers/sampling.py +296 -0
- services/procurement/routers/shipping_information.py +97 -0
- services/production/__init__.py +1 -0
- services/production/agents/__init__.py +5 -0
- services/production/agents/batch_planning_agent.py +815 -0
- services/production/models/__init__.py +25 -0
- services/production/models/batch.py +253 -0
- services/products/helpers/__init__.py +10 -0
- services/products/helpers/boms.py +100 -0
- services/products/helpers/drug_research.py +644 -0
- services/products/helpers/product_component.py +168 -0
- services/products/helpers/product_inventory.py +221 -0
- services/products/helpers/product_pricing.py +123 -0
- services/products/helpers/product_utils.py +32 -0
- services/products/helpers/products.py +81 -0
- services/products/main.py +59 -0
- services/products/models/__init__.py +9 -0
- services/products/models/drug_research.py +138 -0
- services/products/models/product_common.py +60 -0
- services/products/models/product_component.py +1028 -0
- services/products/models/product_inventory.py +118 -0
- services/products/models/product_pricing.py +73 -0
- services/products/models/products.py +151 -0
- services/products/routers/__init__.py +9 -0
- services/products/routers/boms.py +116 -0
- services/products/routers/drug_research.py +115 -0
- services/products/routers/product_components.py +123 -0
- services/products/routers/product_inventory.py +185 -0
- services/products/routers/product_pricing.py +136 -0
- services/products/routers/products.py +165 -0
- services/replenishment/__init__.py +1 -0
- services/replenishment/main.py +46 -0
- services/replenishment/routers/__init__.py +1 -0
- services/replenishment/routers/replenishment.py +20 -0
- services/shifts/helpers/__init__.py +7 -0
- services/shifts/helpers/shift_templates.py +124 -0
- services/shifts/helpers/shifts.py +79 -0
- services/shifts/helpers/timesheets.py +137 -0
- services/shifts/main.py +48 -0
- services/shifts/models/__init__.py +8 -0
- services/shifts/models/shift.py +62 -0
- services/shifts/models/shift_template.py +82 -0
- services/shifts/models/time_range.py +31 -0
- services/shifts/models/timesheet.py +196 -0
- services/shifts/routers/__init__.py +7 -0
- services/shifts/routers/shift_templates.py +97 -0
- services/shifts/routers/shifts.py +117 -0
- services/shifts/routers/timesheets.py +117 -0
- services/shipping/helpers/__init__.py +15 -0
- services/shipping/helpers/carrier.py +78 -0
- services/shipping/helpers/customs_declaration.py +104 -0
- services/shipping/helpers/delivery_note.py +99 -0
- services/shipping/helpers/package.py +95 -0
- services/shipping/helpers/pallet.py +85 -0
- services/shipping/helpers/route.py +93 -0
- services/shipping/helpers/shipping_information.py +82 -0
- services/shipping/helpers/shipping_provider_details.py +59 -0
- services/shipping/helpers/shipping_provider_metadata.py +59 -0
- services/shipping/helpers/vehicle.py +85 -0
- services/shipping/helpers/waybill.py +86 -0
- services/shipping/main.py +64 -0
- services/shipping/models/__init__.py +15 -0
- services/shipping/models/carrier.py +97 -0
- services/shipping/models/customs_declaration.py +138 -0
- services/shipping/models/delivery_note.py +163 -0
- services/shipping/models/package.py +152 -0
- services/shipping/models/pallet.py +137 -0
- services/shipping/models/route.py +120 -0
- services/shipping/models/shipping_information.py +55 -0
- services/shipping/models/shipping_provider_details.py +42 -0
- services/shipping/models/shipping_provider_metadata.py +54 -0
- services/shipping/models/vehicle.py +129 -0
- services/shipping/models/waybill.py +189 -0
- services/shipping/routers/__init__.py +15 -0
- services/shipping/routers/carrier.py +99 -0
- services/shipping/routers/customs_declaration.py +132 -0
- services/shipping/routers/delivery_note.py +150 -0
- services/shipping/routers/package.py +141 -0
- services/shipping/routers/pallet.py +108 -0
- services/shipping/routers/route.py +128 -0
- services/shipping/routers/shipping_information.py +97 -0
- services/shipping/routers/shipping_provider_details.py +80 -0
- services/shipping/routers/shipping_provider_metadata.py +80 -0
- services/shipping/routers/vehicle.py +117 -0
- services/shipping/routers/waybill.py +119 -0
- services/suppliers/helpers/__init__.py +13 -0
- services/suppliers/helpers/supplier_capabilities.py +58 -0
- services/suppliers/helpers/supplier_certifications.py +67 -0
- services/suppliers/helpers/supplier_details.py +58 -0
- services/suppliers/helpers/supplier_financials.py +58 -0
- services/suppliers/helpers/supplier_inventory.py +74 -0
- services/suppliers/helpers/supplier_locations.py +60 -0
- services/suppliers/helpers/supplier_pricing.py +69 -0
- services/suppliers/helpers/supplier_quality.py +69 -0
- services/suppliers/helpers/supplier_shipping.py +69 -0
- services/suppliers/main.py +60 -0
- services/suppliers/models/__init__.py +13 -0
- services/suppliers/models/supplier_capabilities.py +70 -0
- services/suppliers/models/supplier_certifications.py +64 -0
- services/suppliers/models/supplier_details.py +75 -0
- services/suppliers/models/supplier_financials.py +69 -0
- services/suppliers/models/supplier_inventory.py +76 -0
- services/suppliers/models/supplier_locations.py +70 -0
- services/suppliers/models/supplier_pricing.py +74 -0
- services/suppliers/models/supplier_quality.py +74 -0
- services/suppliers/models/supplier_shipping.py +76 -0
- services/suppliers/routers/__init__.py +13 -0
- services/suppliers/routers/supplier_capabilities.py +88 -0
- services/suppliers/routers/supplier_certifications.py +87 -0
- services/suppliers/routers/supplier_details.py +83 -0
- services/suppliers/routers/supplier_financials.py +83 -0
- services/suppliers/routers/supplier_inventory.py +105 -0
- services/suppliers/routers/supplier_locations.py +89 -0
- services/suppliers/routers/supplier_pricing.py +96 -0
- services/suppliers/routers/supplier_quality.py +96 -0
- services/suppliers/routers/supplier_shipping.py +96 -0
- services/supply_allocation/main.py +46 -0
- services/supply_allocation/routers/__init__.py +1 -0
- services/supply_allocation/routers/allocation.py +20 -0
- services/taxonomy/helpers/__init__.py +7 -0
- services/taxonomy/helpers/classes.py +48 -0
- services/taxonomy/helpers/family.py +53 -0
- services/taxonomy/helpers/subclass.py +58 -0
- services/taxonomy/main.py +48 -0
- services/taxonomy/models/__init__.py +7 -0
- services/taxonomy/models/classes.py +52 -0
- services/taxonomy/models/family.py +60 -0
- services/taxonomy/models/subclass.py +50 -0
- services/taxonomy/routers/__init__.py +7 -0
- services/taxonomy/routers/classes.py +78 -0
- services/taxonomy/routers/family.py +77 -0
- services/taxonomy/routers/subclass.py +82 -0
- services/warehouse_execution/__init__.py +1 -0
- services/warehouse_execution/main.py +46 -0
- services/warehouse_execution/routers/__init__.py +1 -0
- services/warehouse_execution/routers/execution.py +21 -0
- services/work_order_agent/__init__.py +17 -0
- services/work_order_agent/agent/__init__.py +17 -0
- services/work_order_agent/agent/work_order_agent.py +658 -0
- services/work_order_agent/tracking/__init__.py +101 -0
- services/work_order_agent/tracking/event_system.py +182 -0
- services/work_order_agent/tracking/state_machine.py +163 -0
- services/work_order_agent/tracking/state_machine_integrator.py +295 -0
- services/work_order_agent/tracking/test_phase2_implementation.py +302 -0
- services/work_order_agent/tracking/time_analysis.py +301 -0
- services/work_order_agent/tracking/tracked_work_order.py +255 -0
- services/work_order_agent/tracking/work_order_adapter.py +367 -0
- services/work_order_agent/tracking/work_order_batch_manager.py +406 -0
- services/work_order_agent/tracking/work_order_repository.py +431 -0
- services/workorders/helpers/__init__.py +5 -0
- services/workorders/helpers/area_room_usage_ledger.py +139 -0
- services/workorders/helpers/batch_execution_records.py +265 -0
- services/workorders/helpers/batch_release_workflows.py +158 -0
- services/workorders/helpers/batch_step_executions.py +145 -0
- services/workorders/helpers/equipment_usage_ledger.py +209 -0
- services/workorders/helpers/executed_bmr_records.py +170 -0
- services/workorders/helpers/executed_bpr_records.py +170 -0
- services/workorders/helpers/executed_instruction_evidence.py +155 -0
- services/workorders/helpers/ipc_result_records.py +134 -0
- services/workorders/helpers/production_batches.py +117 -0
- services/workorders/helpers/work_orders.py +367 -0
- services/workorders/helpers/yield_reconciliation_records.py +158 -0
- services/workorders/main.py +110 -0
- services/workorders/models/__init__.py +5 -0
- services/workorders/models/area_room_usage_ledger.py +154 -0
- services/workorders/models/batch_execution_records.py +575 -0
- services/workorders/models/batch_release_workflows.py +190 -0
- services/workorders/models/batch_step_executions.py +142 -0
- services/workorders/models/equipment_usage_ledger.py +144 -0
- services/workorders/models/executed_bmr_records.py +220 -0
- services/workorders/models/executed_bpr_records.py +220 -0
- services/workorders/models/executed_instruction_evidence.py +128 -0
- services/workorders/models/ipc_result_records.py +164 -0
- services/workorders/models/production_batches.py +181 -0
- services/workorders/models/work_orders.py +255 -0
- services/workorders/models/yield_reconciliation_records.py +175 -0
- services/workorders/routers/__init__.py +5 -0
- services/workorders/routers/area_room_usage_ledger.py +117 -0
- services/workorders/routers/batch_execution_records.py +103 -0
- services/workorders/routers/batch_release_workflows.py +86 -0
- services/workorders/routers/batch_step_executions.py +88 -0
- services/workorders/routers/equipment_usage_ledger.py +115 -0
- services/workorders/routers/executed_bmr_records.py +86 -0
- services/workorders/routers/executed_bpr_records.py +86 -0
- services/workorders/routers/executed_instruction_evidence.py +86 -0
- services/workorders/routers/ipc_result_records.py +86 -0
- services/workorders/routers/production_batches.py +86 -0
- services/workorders/routers/work_orders.py +257 -0
- services/workorders/routers/yield_reconciliation_records.py +86 -0
- src/broca/__init__.py +5 -0
- src/broca/agent.py +201 -0
- src/cerebellum/__init__.py +0 -0
- src/cerebellum/adapter.py +84 -0
- src/cerebellum/capabilities/__init__.py +0 -0
- src/cerebellum/capabilities/agent/__init__.py +0 -0
- src/cerebellum/capabilities/agent/agents.py +65 -0
- src/cerebellum/capabilities/ai/__init__.py +0 -0
- src/cerebellum/capabilities/ai/providers.py +106 -0
- src/cerebellum/capabilities/api/__init__.py +0 -0
- src/cerebellum/capabilities/api/graphql.py +35 -0
- src/cerebellum/capabilities/api/rest_api.py +45 -0
- src/cerebellum/capabilities/api/webhook.py +30 -0
- src/cerebellum/capabilities/browser/__init__.py +0 -0
- src/cerebellum/capabilities/browser/browsers.py +27 -0
- src/cerebellum/capabilities/cloud/__init__.py +0 -0
- src/cerebellum/capabilities/cloud/cloud.py +46 -0
- src/cerebellum/capabilities/communication/__init__.py +0 -0
- src/cerebellum/capabilities/communication/communication.py +62 -0
- src/cerebellum/capabilities/database/__init__.py +0 -0
- src/cerebellum/capabilities/database/elasticsearch.py +40 -0
- src/cerebellum/capabilities/database/influxdb.py +37 -0
- src/cerebellum/capabilities/database/mongodb.py +50 -0
- src/cerebellum/capabilities/database/neo4j.py +32 -0
- src/cerebellum/capabilities/database/redis.py +44 -0
- src/cerebellum/capabilities/enterprise/__init__.py +0 -0
- src/cerebellum/capabilities/enterprise/opensource.py +180 -0
- src/cerebellum/capabilities/enterprise/proprietary.py +313 -0
- src/cerebellum/capabilities/event_streaming/__init__.py +0 -0
- src/cerebellum/capabilities/event_streaming/streaming.py +38 -0
- src/cerebellum/capabilities/infrastructure/__init__.py +0 -0
- src/cerebellum/capabilities/infrastructure/infrastructure.py +30 -0
- src/cerebellum/capabilities/productivity/__init__.py +0 -0
- src/cerebellum/capabilities/productivity/productivity.py +158 -0
- src/cerebellum/capabilities/robotics/__init__.py +0 -0
- src/cerebellum/capabilities/robotics/robotics.py +124 -0
- src/cerebellum/capabilities/runtime/__init__.py +0 -0
- src/cerebellum/capabilities/runtime/runtimes.py +92 -0
- src/cerebellum/capabilities/search/__init__.py +0 -0
- src/cerebellum/capabilities/search/search.py +63 -0
- src/cerebellum/capabilities/source_control/__init__.py +0 -0
- src/cerebellum/capabilities/source_control/source_control.py +113 -0
- src/cerebellum/capabilities/storage/__init__.py +0 -0
- src/cerebellum/capabilities/storage/storage.py +94 -0
- src/cerebellum/capabilities/workflow/__init__.py +0 -0
- src/cerebellum/capabilities/workflow/workflows.py +49 -0
- src/cerebellum/capability.py +108 -0
- src/cerebellum/config.py +157 -0
- src/cerebellum/fallback.py +147 -0
- src/cerebellum/fallback_engine.py +121 -0
- src/cerebellum/key_manager.py +129 -0
- src/cerebellum/keystore.py +179 -0
- src/cerebellum/lifecycle.py +54 -0
- src/cerebellum/metadata.py +61 -0
- src/cerebellum/operator/base.py +25 -0
- src/cerebellum/peripheral.py +92 -0
- src/cerebellum/registry.py +98 -0
- src/cerebellum/resolve_entity_capability.py +259 -0
- src/cingulate/benchmark/__init__.py +23 -0
- src/cingulate/benchmark/reporter.py +102 -0
- src/cingulate/benchmark/runner.py +159 -0
- src/cingulate/benchmark/scenario_runner.py +150 -0
- src/cingulate/benchmark/validator.py +102 -0
- src/cingulate/governance/__init__.py +21 -0
- src/cingulate/governance/architecture_validator.py +194 -0
- src/cingulate/governance/compliance.py +104 -0
- src/cingulate/governance/governance.py +77 -0
- src/cingulate/governance/policy_registry.py +91 -0
- src/cortex/__init__.py +33 -0
- src/cortex/cost.py +71 -0
- src/cortex/counterfactual.py +162 -0
- src/cortex/digital_twin.py +90 -0
- src/cortex/experience.py +83 -0
- src/cortex/feedback.py +144 -0
- src/cortex/loss.py +116 -0
- src/cortex/prediction.py +142 -0
- src/cortex/replay.py +130 -0
- src/cortex/reward.py +113 -0
- src/cortex/simulator.py +102 -0
- src/cortex/world_model.py +180 -0
- src/cortex/world_model_simulation.py +1591 -0
- src/cortex/world_state.py +121 -0
- src/cortex/xavier.py +250 -0
- src/deepdive/__init__.py +29 -0
- src/deepdive/aggregation.py +113 -0
- src/deepdive/digital_twin_aggregator.py +128 -0
- src/deepdive/elasticsearch_adapter.py +110 -0
- src/deepdive/fleet_analytics.py +131 -0
- src/deepdive/knowledge_aggregator.py +130 -0
- src/homeostasis/__init__.py +19 -0
- src/homeostasis/control_plane.py +159 -0
- src/introspection/__init__.py +38 -0
- src/introspection/alerting.py +142 -0
- src/introspection/health.py +101 -0
- src/introspection/lemon.py +243 -0
- src/introspection/logging.py +147 -0
- src/introspection/metrics.py +106 -0
- src/introspection/tracing.py +162 -0
- src/monkey_brain/__init__.py +1 -0
- src/monkey_brain/api/main.py +148 -0
- src/monkey_brain/api/models.py +81 -0
- src/monkey_brain/api/routes/routes/keys.py +106 -0
- src/monkey_brain/api/routes/routes/run.py +169 -0
- src/monkey_brain/api/routes/routes/simulate.py +485 -0
- src/monkey_brain/dlm/__init__.py +44 -0
- src/monkey_brain/dlm/dlm.py +139 -0
- src/monkey_brain/dlm/gc.py +115 -0
- src/monkey_brain/dlm/lifecycle.py +149 -0
- src/monkey_brain/dlm/orphans.py +99 -0
- src/monkey_brain/dlm/storage.py +149 -0
- src/monkey_brain/dlm/ttl.py +140 -0
- src/monkey_brain/documents/__init__.py +0 -0
- src/monkey_brain/documents/document_ocr.py +6 -0
- src/monkey_brain/kernel/__init__.py +53 -0
- src/monkey_brain/kernel/capability_interface.py +144 -0
- src/monkey_brain/kernel/classifier/__init__.py +1 -0
- src/monkey_brain/kernel/classifier/embed_classifier.py +125 -0
- src/monkey_brain/kernel/classifier/intent_examples.py +106 -0
- src/monkey_brain/kernel/dag.py +23 -0
- src/monkey_brain/kernel/execution_state.py +257 -0
- src/monkey_brain/kernel/goal_planner.py +85 -0
- src/monkey_brain/kernel/goal_router.py +20 -0
- src/monkey_brain/kernel/goals/__init__.py +1 -0
- src/monkey_brain/kernel/goals/goal.py +130 -0
- src/monkey_brain/kernel/goals/goal_bootstrap.py +38 -0
- src/monkey_brain/kernel/goals/goal_classifier.py +132 -0
- src/monkey_brain/kernel/goals/goal_registry.py +75 -0
- src/monkey_brain/kernel/intents/__init__.py +1 -0
- src/monkey_brain/kernel/intents/event_adapter.py +246 -0
- src/monkey_brain/kernel/intents/helpers.py +13 -0
- src/monkey_brain/kernel/intents/intent_registry.py +705 -0
- src/monkey_brain/kernel/intents/intent_router.py +102 -0
- src/monkey_brain/kernel/intents/predicates/approval_create.py +9 -0
- src/monkey_brain/kernel/intents/predicates/approval_decision.py +9 -0
- src/monkey_brain/kernel/intents/predicates/approval_hold.py +9 -0
- src/monkey_brain/kernel/intents/predicates/approval_query.py +9 -0
- src/monkey_brain/kernel/intents/predicates/batch_close.py +9 -0
- src/monkey_brain/kernel/intents/predicates/batch_creation.py +9 -0
- src/monkey_brain/kernel/intents/predicates/batch_delete.py +9 -0
- src/monkey_brain/kernel/intents/predicates/batch_hold.py +9 -0
- src/monkey_brain/kernel/intents/predicates/batch_record.py +9 -0
- src/monkey_brain/kernel/intents/predicates/batch_update.py +9 -0
- src/monkey_brain/kernel/intents/predicates/change_control.py +49 -0
- src/monkey_brain/kernel/intents/predicates/compliance_audit.py +14 -0
- src/monkey_brain/kernel/intents/predicates/decision_intelligence.py +9 -0
- src/monkey_brain/kernel/intents/predicates/drug_research.py +9 -0
- src/monkey_brain/kernel/intents/predicates/fuzzy_match.py +19 -0
- src/monkey_brain/kernel/intents/predicates/production_kpi.py +9 -0
- src/monkey_brain/kernel/intents/predicates/sop_create.py +9 -0
- src/monkey_brain/kernel/intents/predicates/sop_query.py +9 -0
- src/monkey_brain/kernel/intents/predicates/sop_update.py +9 -0
- src/monkey_brain/kernel/intents/predicates/warehouse_shipping.py +9 -0
- src/monkey_brain/kernel/intents/predicates/work_order_create.py +9 -0
- src/monkey_brain/kernel/intents/predicates/work_order_delete.py +9 -0
- src/monkey_brain/kernel/intents/predicates/work_order_hold.py +9 -0
- src/monkey_brain/kernel/intents/predicates/work_order_query.py +9 -0
- src/monkey_brain/kernel/intents/predicates/work_order_status.py +9 -0
- src/monkey_brain/kernel/intents/predicates/work_order_update.py +9 -0
- src/monkey_brain/kernel/intents/predicates/worker.py +9 -0
- src/monkey_brain/kernel/intents/telemetry_adapter.py +274 -0
- src/monkey_brain/kernel/intents/utils.py +68 -0
- src/monkey_brain/kernel/learning.py +98 -0
- src/monkey_brain/kernel/llm_explorer.py +188 -0
- src/monkey_brain/kernel/loss.py +81 -0
- src/monkey_brain/kernel/nlp/__init__.py +1 -0
- src/monkey_brain/kernel/nlp/compat.py +23 -0
- src/monkey_brain/kernel/nlp/models.py +10 -0
- src/monkey_brain/kernel/nlp/question_analyzer.py +203 -0
- src/monkey_brain/kernel/nlp/spacy_parser.py +53 -0
- src/monkey_brain/kernel/observer.py +97 -0
- src/monkey_brain/kernel/parser/__init__.py +3 -0
- src/monkey_brain/kernel/parser/ast.py +28 -0
- src/monkey_brain/kernel/parser/extractors/__init__.py +11 -0
- src/monkey_brain/kernel/parser/extractors/entities.py +21 -0
- src/monkey_brain/kernel/parser/extractors/filters.py +16 -0
- src/monkey_brain/kernel/parser/extractors/projections.py +36 -0
- src/monkey_brain/kernel/parser/extractors/verbs.py +31 -0
- src/monkey_brain/kernel/parser/parser.py +57 -0
- src/monkey_brain/kernel/parser/rules.py +75 -0
- src/monkey_brain/kernel/pipeline.py +44 -0
- src/monkey_brain/kernel/planner.py +57 -0
- src/monkey_brain/kernel/rl/__init__.py +33 -0
- src/monkey_brain/kernel/rl/learner.py +98 -0
- src/monkey_brain/kernel/rl/policy.py +254 -0
- src/monkey_brain/kernel/rl/reward.py +117 -0
- src/monkey_brain/kernel/rl/transition.py +112 -0
- src/monkey_brain/persistence/__init__.py +47 -0
- src/monkey_brain/persistence/adapters.py +49 -0
- src/monkey_brain/persistence/events.py +105 -0
- src/monkey_brain/persistence/manager.py +124 -0
- src/monkey_brain/persistence/mongodb_adapter.py +91 -0
- src/monkey_brain/persistence/redis_adapter.py +93 -0
- src/monkey_brain/persistence/reducer.py +111 -0
- src/monkey_brain/runtime/__init__.py +49 -0
- src/monkey_brain/runtime/depedencies.py +8 -0
- src/monkey_brain/runtime/engine.py +183 -0
- src/monkey_brain/runtime/message_bus.py +82 -0
- src/monkey_brain/runtime/process.py +144 -0
- src/monkey_brain/runtime/resource_manager.py +100 -0
- src/monkey_brain/runtime/routers.py +8 -0
- src/monkey_brain/runtime/runtime.py +199 -0
- src/monkey_brain/runtime/scheduler.py +165 -0
- src/monkey_brain/runtime/supervisor.py +133 -0
- src/monkey_brain/runtime/worker_pool.py +111 -0
- src/plasticity/seed/__init__.py +30 -0
- src/plasticity/seed/benchmark_generator.py +105 -0
- src/plasticity/seed/event_generator.py +122 -0
- src/plasticity/seed/scenario_builder.py +134 -0
- src/plasticity/seed/seed_data.py +206 -0
- src/plasticity/seed/seeder.py +122 -0
- src/plasticity/testing/__init__.py +28 -0
- src/plasticity/testing/performance.py +131 -0
- src/plasticity/testing/profiler.py +255 -0
- src/plasticity/testing/reporter.py +84 -0
- src/plasticity/testing/runner.py +209 -0
- src/sync/__init__.py +12 -0
- src/sync/cloud_aggregator.py +63 -0
- src/sync/edge_node.py +51 -0
- src/sync/sync_manager.py +74 -0
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
from datetime import datetime, timezone
|
|
2
|
+
from typing import Optional, Literal
|
|
3
|
+
from pydantic import BaseModel, Field, model_validator
|
|
4
|
+
|
|
5
|
+
LineType = Literal["Assembly", "Continuous", "Batch"]
|
|
6
|
+
LineStatus = Literal["Operational", "Maintenance", "Down", "Stalled"]
|
|
7
|
+
|
|
8
|
+
def utc_now() -> datetime:
|
|
9
|
+
return datetime.now(timezone.utc)
|
|
10
|
+
|
|
11
|
+
def ensure_utc(dt: Optional[datetime]) -> Optional[datetime]:
|
|
12
|
+
if dt is None:
|
|
13
|
+
return None
|
|
14
|
+
if dt.tzinfo is None:
|
|
15
|
+
return dt.replace(tzinfo=timezone.utc)
|
|
16
|
+
return dt.astimezone(timezone.utc)
|
|
17
|
+
|
|
18
|
+
class IndustrialLine(BaseModel):
|
|
19
|
+
id: str
|
|
20
|
+
name: str
|
|
21
|
+
plant_id: str
|
|
22
|
+
type: LineType
|
|
23
|
+
takt_time: float = Field(..., gt=0, description="Cycle time in seconds")
|
|
24
|
+
status: LineStatus
|
|
25
|
+
efficiency: int = Field(..., ge=0, le=100)
|
|
26
|
+
description: Optional[str] = None
|
|
27
|
+
created_at: datetime = Field(default_factory=utc_now)
|
|
28
|
+
updated_at: datetime = Field(default_factory=utc_now)
|
|
29
|
+
|
|
30
|
+
@model_validator(mode="after")
|
|
31
|
+
def normalize_datetimes(self) -> "IndustrialLine":
|
|
32
|
+
self.created_at = ensure_utc(self.created_at)
|
|
33
|
+
self.updated_at = ensure_utc(self.updated_at)
|
|
34
|
+
return self
|
|
35
|
+
|
|
36
|
+
@model_validator(mode="after")
|
|
37
|
+
def check_efficiency_vs_status(self) -> "IndustrialLine":
|
|
38
|
+
if self.status == "Down" and self.efficiency > 0:
|
|
39
|
+
raise ValueError("efficiency must be 0 when status is 'Down'")
|
|
40
|
+
if self.status == "Maintenance" and self.efficiency >= 100:
|
|
41
|
+
raise ValueError("efficiency must be < 100 when status is 'Maintenance'")
|
|
42
|
+
return self
|
|
43
|
+
|
|
44
|
+
class IndustrialLineCreate(IndustrialLine):
|
|
45
|
+
pass
|
|
46
|
+
|
|
47
|
+
class IndustrialLineUpdate(BaseModel):
|
|
48
|
+
name: Optional[str] = None
|
|
49
|
+
type: Optional[LineType] = None
|
|
50
|
+
takt_time: Optional[float] = Field(None, gt=0)
|
|
51
|
+
status: Optional[LineStatus] = None
|
|
52
|
+
efficiency: Optional[int] = Field(None, ge=0, le=100)
|
|
53
|
+
description: Optional[str] = None
|
|
54
|
+
updated_at: datetime = Field(default_factory=utc_now)
|
|
55
|
+
|
|
56
|
+
@model_validator(mode="after")
|
|
57
|
+
def check_efficiency_vs_status(self) -> "IndustrialLineUpdate":
|
|
58
|
+
if self.status == "Down" and self.efficiency is not None and self.efficiency > 0:
|
|
59
|
+
raise ValueError("efficiency must be 0 when status is 'Down'")
|
|
60
|
+
if self.status == "Maintenance" and self.efficiency is not None and self.efficiency >= 100:
|
|
61
|
+
raise ValueError("efficiency must be < 100 when status is 'Maintenance'")
|
|
62
|
+
return self
|
|
63
|
+
|
|
64
|
+
class IndustrialLineResponse(IndustrialLine):
|
|
65
|
+
class Config:
|
|
66
|
+
from_attributes = True
|
|
67
|
+
|
|
68
|
+
class PaginatedLineResponse(BaseModel):
|
|
69
|
+
total: int
|
|
70
|
+
page: int
|
|
71
|
+
page_size: int
|
|
72
|
+
results: list[IndustrialLineResponse]
|
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
from datetime import datetime, timezone
|
|
2
|
+
from typing import Optional, Literal
|
|
3
|
+
from pydantic import BaseModel, Field, model_validator, EmailStr
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
PlantStatus = Literal["Active", "Reduced Capacity", "Shutdown", "Maintenance", "Decommissioned"]
|
|
7
|
+
Timezone = Literal["UTC", "CET", "IST", "EST", "PST", "JST", "CST", "GST", "AEST"]
|
|
8
|
+
PlantType = Literal[
|
|
9
|
+
"Production",
|
|
10
|
+
"Packaging",
|
|
11
|
+
"R&D",
|
|
12
|
+
"Warehouse",
|
|
13
|
+
]
|
|
14
|
+
CertificationStatus = Literal["Valid", "Expired", "Pending Renewal"]
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
def utc_now() -> datetime:
|
|
18
|
+
return datetime.now(timezone.utc)
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
def ensure_utc(dt: Optional[datetime]) -> Optional[datetime]:
|
|
22
|
+
if dt is None:
|
|
23
|
+
return None
|
|
24
|
+
if dt.tzinfo is None:
|
|
25
|
+
return dt.replace(tzinfo=timezone.utc)
|
|
26
|
+
return dt.astimezone(timezone.utc)
|
|
27
|
+
|
|
28
|
+
# ── Sub-models ────────────────────────────────────────────────────────────────
|
|
29
|
+
|
|
30
|
+
class GeoCoordinates(BaseModel):
|
|
31
|
+
latitude: float = Field(..., ge=-90.0, le=90.0)
|
|
32
|
+
longitude: float = Field(..., ge=-180.0, le=180.0)
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
class ContactInfo(BaseModel):
|
|
36
|
+
name: str
|
|
37
|
+
role: str
|
|
38
|
+
email: Optional[str] = None
|
|
39
|
+
phone: Optional[str] = None
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
class Certification(BaseModel):
|
|
43
|
+
name: str
|
|
44
|
+
issued_by: Optional[str] = None
|
|
45
|
+
issue_date: Optional[str] = None
|
|
46
|
+
expiry_date: Optional[str] = None
|
|
47
|
+
status: CertificationStatus = "Valid"
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
class ShiftSchedule(BaseModel):
|
|
51
|
+
shifts_per_day: int = Field(..., ge=1, le=3)
|
|
52
|
+
operating_days_per_week: int = Field(..., ge=1, le=7)
|
|
53
|
+
hours_per_shift: float = Field(..., ge=1.0, le=12.0)
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
class UtilityInfo(BaseModel):
|
|
57
|
+
power_source: Optional[str] = None
|
|
58
|
+
power_capacity_kw: Optional[float] = Field(None, ge=0)
|
|
59
|
+
water_source: Optional[str] = None
|
|
60
|
+
water_consumption_m3_day: Optional[float] = Field(None, ge=0)
|
|
61
|
+
has_backup_generator: bool = False
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
# ── Core model ────────────────────────────────────────────────────────────────
|
|
65
|
+
|
|
66
|
+
class IndustrialPlant(BaseModel):
|
|
67
|
+
# Identity
|
|
68
|
+
id: str
|
|
69
|
+
name: str
|
|
70
|
+
plant_code: Optional[str] = Field(None, description="Internal short code e.g. PLT-001")
|
|
71
|
+
type: PlantType
|
|
72
|
+
|
|
73
|
+
# Location
|
|
74
|
+
location: str
|
|
75
|
+
address: str
|
|
76
|
+
country: str
|
|
77
|
+
geo: Optional[GeoCoordinates] = None
|
|
78
|
+
timezone: Timezone
|
|
79
|
+
|
|
80
|
+
# Operations
|
|
81
|
+
status: PlantStatus
|
|
82
|
+
capacity_utilization: int = Field(..., ge=0, le=100, description="Current utilization %")
|
|
83
|
+
total_area_sqm: Optional[float] = Field(None, ge=0, description="Total floor area in m²")
|
|
84
|
+
employee_count: Optional[int] = Field(None, ge=0)
|
|
85
|
+
established_year: Optional[int] = Field(None, ge=1800, le=2100)
|
|
86
|
+
|
|
87
|
+
# People
|
|
88
|
+
manager: str
|
|
89
|
+
manager_contact: Optional[ContactInfo] = None
|
|
90
|
+
emergency_contact: Optional[ContactInfo] = None
|
|
91
|
+
|
|
92
|
+
# Scheduling & utilities
|
|
93
|
+
shift_schedule: Optional[ShiftSchedule] = None
|
|
94
|
+
utilities: Optional[UtilityInfo] = None
|
|
95
|
+
|
|
96
|
+
# Compliance
|
|
97
|
+
certifications: Optional[list[Certification]] = None
|
|
98
|
+
regulatory_body: Optional[str] = None
|
|
99
|
+
|
|
100
|
+
# Meta
|
|
101
|
+
notes: Optional[str] = None
|
|
102
|
+
description: Optional[str] = None
|
|
103
|
+
|
|
104
|
+
created_at: datetime = Field(default_factory=utc_now)
|
|
105
|
+
updated_at: datetime = Field(default_factory=utc_now)
|
|
106
|
+
|
|
107
|
+
@model_validator(mode="after")
|
|
108
|
+
def normalize_and_validate(self):
|
|
109
|
+
self.created_at = ensure_utc(self.created_at)
|
|
110
|
+
self.updated_at = ensure_utc(self.updated_at)
|
|
111
|
+
return self
|
|
112
|
+
|
|
113
|
+
@model_validator(mode="after")
|
|
114
|
+
def check_utilization_vs_status(self) -> "IndustrialPlant":
|
|
115
|
+
if self.status == "Shutdown" and self.capacity_utilization > 0:
|
|
116
|
+
raise ValueError("capacity_utilization must be 0 when status is 'Shutdown'")
|
|
117
|
+
if self.status == "Reduced Capacity" and self.capacity_utilization >= 100:
|
|
118
|
+
raise ValueError("capacity_utilization must be < 100 when status is 'Reduced Capacity'")
|
|
119
|
+
return self
|
|
120
|
+
|
|
121
|
+
|
|
122
|
+
# ── Request / Response schemas ────────────────────────────────────────────────
|
|
123
|
+
|
|
124
|
+
class IndustrialPlantCreate(IndustrialPlant):
|
|
125
|
+
pass
|
|
126
|
+
|
|
127
|
+
|
|
128
|
+
class IndustrialPlantUpdate(BaseModel):
|
|
129
|
+
name: Optional[str] = None
|
|
130
|
+
plant_code: Optional[str] = None
|
|
131
|
+
type: Optional[PlantType] = None
|
|
132
|
+
location: Optional[str] = None
|
|
133
|
+
address: Optional[str] = None
|
|
134
|
+
country: Optional[str] = None
|
|
135
|
+
geo: Optional[GeoCoordinates] = None
|
|
136
|
+
timezone: Optional[Timezone] = None
|
|
137
|
+
status: Optional[PlantStatus] = None
|
|
138
|
+
capacity_utilization: Optional[int] = Field(None, ge=0, le=100)
|
|
139
|
+
total_area_sqm: Optional[float] = Field(None, ge=0)
|
|
140
|
+
employee_count: Optional[int] = Field(None, ge=0)
|
|
141
|
+
established_year: Optional[int] = Field(None, ge=1800, le=2100)
|
|
142
|
+
manager: Optional[str] = None
|
|
143
|
+
manager_contact: Optional[ContactInfo] = None
|
|
144
|
+
emergency_contact: Optional[ContactInfo] = None
|
|
145
|
+
shift_schedule: Optional[ShiftSchedule] = None
|
|
146
|
+
utilities: Optional[UtilityInfo] = None
|
|
147
|
+
certifications: Optional[list[Certification]] = None
|
|
148
|
+
regulatory_body: Optional[str] = None
|
|
149
|
+
notes: Optional[str] = None
|
|
150
|
+
description: Optional[str] = None
|
|
151
|
+
created_at: datetime = Field(default_factory=utc_now)
|
|
152
|
+
updated_at: datetime = Field(default_factory=utc_now)
|
|
153
|
+
|
|
154
|
+
|
|
155
|
+
class IndustrialPlantResponse(IndustrialPlant):
|
|
156
|
+
class Config:
|
|
157
|
+
from_attributes = True
|
|
158
|
+
|
|
159
|
+
|
|
160
|
+
class PaginatedPlantResponse(BaseModel):
|
|
161
|
+
total: int
|
|
162
|
+
page: int
|
|
163
|
+
page_size: int
|
|
164
|
+
results: list[IndustrialPlantResponse]
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
"""Pydantic models for plant location hierarchy."""
|
|
2
|
+
|
|
3
|
+
from typing import Optional, List
|
|
4
|
+
from datetime import datetime
|
|
5
|
+
from pydantic import BaseModel, Field
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class LocationBase(BaseModel):
|
|
9
|
+
"""Base location model."""
|
|
10
|
+
name: str = Field(..., description="Location name")
|
|
11
|
+
location_id: str = Field(..., description="Location ID/code")
|
|
12
|
+
type: str = Field(..., description="Location type (plant, building, floor, room, bay)")
|
|
13
|
+
level: int = Field(..., ge=1, le=5, description="Hierarchy level (1-5)")
|
|
14
|
+
path: str = Field(..., description="Full hierarchical path")
|
|
15
|
+
description: Optional[str] = Field(None, description="Detailed description")
|
|
16
|
+
status: str = Field("Operational", description="Operational status")
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
class LocationCreate(LocationBase):
|
|
20
|
+
"""Model for creating locations."""
|
|
21
|
+
parent_id: Optional[str] = Field(None, description="Parent location ID")
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
class LocationUpdate(BaseModel):
|
|
25
|
+
"""Model for updating locations."""
|
|
26
|
+
name: Optional[str] = Field(None, description="Location name")
|
|
27
|
+
description: Optional[str] = Field(None, description="Detailed description")
|
|
28
|
+
status: Optional[str] = Field(None, description="Operational status")
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
class LocationResponse(LocationBase):
|
|
32
|
+
"""Model for location responses."""
|
|
33
|
+
id: str = Field(..., description="MongoDB ID")
|
|
34
|
+
parent_id: Optional[str] = Field(None, description="Parent location ID")
|
|
35
|
+
plant_id: Optional[str] = Field(None, description="Plant ID")
|
|
36
|
+
building_id: Optional[str] = Field(None, description="Building ID")
|
|
37
|
+
floor_id: Optional[str] = Field(None, description="Floor ID")
|
|
38
|
+
room_id: Optional[str] = Field(None, description="Room ID")
|
|
39
|
+
bay_id: Optional[str] = Field(None, description="Bay ID")
|
|
40
|
+
cleanroom_class: Optional[str] = Field(None, description="ISO cleanroom classification")
|
|
41
|
+
workstation_id: Optional[str] = Field(None, description="Associated workstation ID")
|
|
42
|
+
room_number: Optional[str] = Field(None, description="Room number")
|
|
43
|
+
bay_number: Optional[str] = Field(None, description="Bay number")
|
|
44
|
+
floor_number: Optional[int] = Field(None, description="Floor number")
|
|
45
|
+
has_ahu: Optional[bool] = Field(None, description="Has AHU system")
|
|
46
|
+
has_exhaust: Optional[bool] = Field(None, description="Has exhaust system")
|
|
47
|
+
temperature_controlled: Optional[bool] = Field(None, description="Temperature controlled")
|
|
48
|
+
humidity_controlled: Optional[bool] = Field(None, description="Humidity controlled")
|
|
49
|
+
created_at: datetime = Field(..., description="Creation timestamp")
|
|
50
|
+
updated_at: datetime = Field(..., description="Last update timestamp")
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
class PaginatedLocationResponse(BaseModel):
|
|
54
|
+
"""Paginated response model for locations."""
|
|
55
|
+
total: int = Field(..., description="Total number of locations")
|
|
56
|
+
page: int = Field(..., description="Current page")
|
|
57
|
+
page_size: int = Field(..., description="Items per page")
|
|
58
|
+
results: List[LocationResponse] = Field(..., description="Location results")
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
class LocationHierarchyResponse(BaseModel):
|
|
62
|
+
"""Model for location hierarchy responses."""
|
|
63
|
+
plant: Optional[LocationResponse] = Field(None, description="Plant location")
|
|
64
|
+
building: Optional[LocationResponse] = Field(None, description="Building location")
|
|
65
|
+
floor: Optional[LocationResponse] = Field(None, description="Floor location")
|
|
66
|
+
room: Optional[LocationResponse] = Field(None, description="Room location")
|
|
67
|
+
bay: Optional[LocationResponse] = Field(None, description="Bay location")
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
class LocationWithChildrenResponse(BaseModel):
|
|
71
|
+
"""Model for location with children."""
|
|
72
|
+
location: LocationResponse = Field(..., description="Location details")
|
|
73
|
+
children: List[LocationResponse] = Field(default_factory=list, description="Child locations")
|
|
74
|
+
children_count: int = Field(0, description="Number of child locations")
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
from datetime import datetime, timezone
|
|
2
|
+
from typing import Optional, Literal
|
|
3
|
+
from pydantic import BaseModel, Field, field_validator, model_validator
|
|
4
|
+
|
|
5
|
+
StageType = Literal["Assembly", "Continuous", "Batch"]
|
|
6
|
+
StageStatus = Literal["Operational", "Maintenance", "Down","Decommissioned"]
|
|
7
|
+
|
|
8
|
+
def utc_now() -> datetime:
|
|
9
|
+
return datetime.now(timezone.utc)
|
|
10
|
+
|
|
11
|
+
def ensure_utc(dt: Optional[datetime]) -> Optional[datetime]:
|
|
12
|
+
if dt is None:
|
|
13
|
+
return None
|
|
14
|
+
if dt.tzinfo is None:
|
|
15
|
+
return dt.replace(tzinfo=timezone.utc)
|
|
16
|
+
return dt.astimezone(timezone.utc)
|
|
17
|
+
|
|
18
|
+
def _normalize_stage_status(value):
|
|
19
|
+
if value == "Active":
|
|
20
|
+
return "Operational"
|
|
21
|
+
return value
|
|
22
|
+
|
|
23
|
+
class IndustrialStage(BaseModel):
|
|
24
|
+
id: str
|
|
25
|
+
name: str
|
|
26
|
+
plant_id: Optional[str] = None
|
|
27
|
+
type: StageType
|
|
28
|
+
takt_time: float = Field(..., gt=0, description="Cycle time in seconds")
|
|
29
|
+
status: StageStatus
|
|
30
|
+
line_id: Optional[str] = None
|
|
31
|
+
efficiency: int = Field(..., ge=0, le=100)
|
|
32
|
+
description: Optional[str] = None
|
|
33
|
+
last_pm:Optional[str] = None
|
|
34
|
+
created_at: datetime = Field(default_factory=utc_now)
|
|
35
|
+
updated_at: datetime = Field(default_factory=utc_now)
|
|
36
|
+
|
|
37
|
+
@model_validator(mode="after")
|
|
38
|
+
def normalize_datetimes(self) -> "IndustrialStage":
|
|
39
|
+
self.created_at = ensure_utc(self.created_at)
|
|
40
|
+
self.updated_at = ensure_utc(self.updated_at)
|
|
41
|
+
return self
|
|
42
|
+
|
|
43
|
+
@field_validator("status", mode="before")
|
|
44
|
+
@classmethod
|
|
45
|
+
def normalize_status(cls, value):
|
|
46
|
+
return _normalize_stage_status(value)
|
|
47
|
+
|
|
48
|
+
@model_validator(mode="after")
|
|
49
|
+
def check_efficiency_vs_status(self) -> "IndustrialStage":
|
|
50
|
+
if self.status == "Down" and self.efficiency > 0:
|
|
51
|
+
raise ValueError("efficiency must be 0 when status is 'Down'")
|
|
52
|
+
if self.status == "Maintenance" and self.efficiency >= 100:
|
|
53
|
+
raise ValueError("efficiency must be < 100 when status is 'Maintenance'")
|
|
54
|
+
return self
|
|
55
|
+
|
|
56
|
+
class IndustrialStageCreate(IndustrialStage):
|
|
57
|
+
pass
|
|
58
|
+
|
|
59
|
+
class IndustrialStageUpdate(BaseModel):
|
|
60
|
+
name: str
|
|
61
|
+
plant_name: Optional[str] = None
|
|
62
|
+
type: StageType
|
|
63
|
+
takt_time: float = Field(..., gt=0, description="Cycle time in seconds")
|
|
64
|
+
status: StageStatus
|
|
65
|
+
line_id: Optional[str] = None
|
|
66
|
+
efficiency: int = Field(..., ge=0, le=100)
|
|
67
|
+
description: Optional[str] = None
|
|
68
|
+
last_pm:Optional[str] = None
|
|
69
|
+
updated_at: datetime = Field(default_factory=utc_now)
|
|
70
|
+
|
|
71
|
+
@field_validator("status", mode="before")
|
|
72
|
+
@classmethod
|
|
73
|
+
def normalize_status(cls, value):
|
|
74
|
+
return _normalize_stage_status(value)
|
|
75
|
+
|
|
76
|
+
@model_validator(mode="after")
|
|
77
|
+
def check_efficiency_vs_status(self) -> "IndustrialStageUpdate":
|
|
78
|
+
if self.status == "Down" and self.efficiency is not None and self.efficiency > 0:
|
|
79
|
+
raise ValueError("efficiency must be 0 when status is 'Down'")
|
|
80
|
+
if self.status == "Maintenance" and self.efficiency is not None and self.efficiency >= 100:
|
|
81
|
+
raise ValueError("efficiency must be < 100 when status is 'Maintenance'")
|
|
82
|
+
return self
|
|
83
|
+
|
|
84
|
+
class IndustrialStageResponse(IndustrialStage):
|
|
85
|
+
class Config:
|
|
86
|
+
from_attributes = True
|
|
87
|
+
|
|
88
|
+
class PaginatedStageResponse(BaseModel):
|
|
89
|
+
total: int
|
|
90
|
+
page: int
|
|
91
|
+
page_size: int
|
|
92
|
+
results: list[IndustrialStageResponse]
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
from datetime import datetime, timezone
|
|
2
|
+
from typing import Optional
|
|
3
|
+
from pydantic import BaseModel, Field, model_validator
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
def utc_now() -> datetime:
|
|
7
|
+
return datetime.now(timezone.utc)
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
def ensure_utc(dt: Optional[datetime]) -> Optional[datetime]:
|
|
11
|
+
if dt is None:
|
|
12
|
+
return None
|
|
13
|
+
if dt.tzinfo is None:
|
|
14
|
+
return dt.replace(tzinfo=timezone.utc)
|
|
15
|
+
return dt.astimezone(timezone.utc)
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
class Worker(BaseModel):
|
|
19
|
+
"""Represents a worker in the manufacturing facility."""
|
|
20
|
+
worker_id: str = Field(..., min_length=1, description="Unique identifier for the worker")
|
|
21
|
+
name: str = Field(..., min_length=1, description="Full name of the worker")
|
|
22
|
+
role: str = Field(..., min_length=1, description="Job role or position")
|
|
23
|
+
worker_type: str = Field(..., description="Type of worker (Plant Worker, Line Worker, Workstation Worker)")
|
|
24
|
+
|
|
25
|
+
# Location/assignment fields
|
|
26
|
+
plant_id: Optional[str] = Field(None, description="ID of the plant where worker is assigned")
|
|
27
|
+
line_id: Optional[str] = Field(None, description="ID of the production line where worker is assigned")
|
|
28
|
+
workstation_id: Optional[str] = Field(None, description="ID of the specific workstation where worker is assigned")
|
|
29
|
+
|
|
30
|
+
# Hierarchy/management fields
|
|
31
|
+
reports_to_worker_id: Optional[str] = Field(None, description="ID of the worker this worker reports to")
|
|
32
|
+
|
|
33
|
+
# Timestamps
|
|
34
|
+
created_at: datetime = Field(default_factory=utc_now, description="When the worker record was created")
|
|
35
|
+
updated_at: datetime = Field(default_factory=utc_now, description="When the worker record was last updated")
|
|
36
|
+
|
|
37
|
+
# Device assignment (new field)
|
|
38
|
+
device_id: Optional[str] = Field(None, description="ID of the device assigned to this worker")
|
|
39
|
+
|
|
40
|
+
@model_validator(mode="after")
|
|
41
|
+
def normalize_datetimes(self) -> "Worker":
|
|
42
|
+
self.created_at = ensure_utc(self.created_at)
|
|
43
|
+
self.updated_at = ensure_utc(self.updated_at)
|
|
44
|
+
return self
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
class WorkerCreate(Worker):
|
|
48
|
+
"""Model for creating a new worker."""
|
|
49
|
+
pass
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
class WorkerUpdate(BaseModel):
|
|
53
|
+
"""Model for updating worker information."""
|
|
54
|
+
name: Optional[str] = Field(None, min_length=1)
|
|
55
|
+
role: Optional[str] = Field(None, min_length=1)
|
|
56
|
+
worker_type: Optional[str] = None
|
|
57
|
+
plant_id: Optional[str] = None
|
|
58
|
+
line_id: Optional[str] = None
|
|
59
|
+
workstation_id: Optional[str] = None
|
|
60
|
+
reports_to_worker_id: Optional[str] = None
|
|
61
|
+
device_id: Optional[str] = None
|
|
62
|
+
updated_at: datetime = Field(default_factory=utc_now)
|
|
63
|
+
|
|
64
|
+
@model_validator(mode="after")
|
|
65
|
+
def normalize_update_datetimes(self) -> "WorkerUpdate":
|
|
66
|
+
self.updated_at = ensure_utc(self.updated_at)
|
|
67
|
+
return self
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
class WorkerResponse(Worker):
|
|
71
|
+
"""Response model for worker data."""
|
|
72
|
+
class Config:
|
|
73
|
+
from_attributes = True
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
from datetime import datetime, timezone
|
|
2
|
+
from typing import Optional, Literal
|
|
3
|
+
from pydantic import BaseModel, Field, model_validator
|
|
4
|
+
|
|
5
|
+
WorkstationMode = Literal["Robotic", "Manual", "Hybrid"]
|
|
6
|
+
WorkstationStatus = Literal["Active", "Alert", "Idle", "Offline"]
|
|
7
|
+
|
|
8
|
+
# ─────────────────────────────────────────────
|
|
9
|
+
# UTILS (INLINE SAFE UTC HANDLING)
|
|
10
|
+
# ─────────────────────────────────────────────
|
|
11
|
+
|
|
12
|
+
def utc_now() -> datetime:
|
|
13
|
+
return datetime.now(timezone.utc)
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
def ensure_utc(dt: Optional[datetime]) -> Optional[datetime]:
|
|
17
|
+
if dt is None:
|
|
18
|
+
return None
|
|
19
|
+
if dt.tzinfo is None:
|
|
20
|
+
return dt.replace(tzinfo=timezone.utc)
|
|
21
|
+
return dt.astimezone(timezone.utc)
|
|
22
|
+
|
|
23
|
+
class Workstation(BaseModel):
|
|
24
|
+
id: str
|
|
25
|
+
name: str
|
|
26
|
+
line_id: Optional[str] = None
|
|
27
|
+
stage_id: Optional[str] = None
|
|
28
|
+
mode: WorkstationMode
|
|
29
|
+
status: WorkstationStatus
|
|
30
|
+
description: Optional[str] = None
|
|
31
|
+
operator: Optional[str] = Field(None, description="Required for Manual and Hybrid modes")
|
|
32
|
+
cycle_time_actual: float = Field(..., ge=0, description="Actual cycle time in seconds")
|
|
33
|
+
cycle_time_target: float = Field(..., gt=0, description="Target cycle time in seconds")
|
|
34
|
+
is_bottleneck: bool = Field(..., description="True when cycle_time_actual exceeds cycle_time_target")
|
|
35
|
+
created_at: datetime = Field(default_factory=utc_now)
|
|
36
|
+
updated_at: datetime = Field(default_factory=utc_now)
|
|
37
|
+
|
|
38
|
+
@model_validator(mode="after")
|
|
39
|
+
def normalize_datetimes(self) -> "Workstation":
|
|
40
|
+
self.created_at = ensure_utc(self.created_at)
|
|
41
|
+
self.updated_at = ensure_utc(self.updated_at)
|
|
42
|
+
return self
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
@model_validator(mode="after")
|
|
46
|
+
def check_constraints(self) -> "Workstation":
|
|
47
|
+
# Operator rules
|
|
48
|
+
if self.mode == "Robotic" and self.operator is not None:
|
|
49
|
+
raise ValueError("operator must be None when mode is 'Robotic'")
|
|
50
|
+
if self.mode in ("Manual", "Hybrid") and not self.operator:
|
|
51
|
+
raise ValueError(f"operator is required when mode is '{self.mode}'")
|
|
52
|
+
|
|
53
|
+
# Idle stations must have zero actual cycle time
|
|
54
|
+
if self.status == "Idle" and self.cycle_time_actual > 0:
|
|
55
|
+
raise ValueError("cycle_time_actual must be 0 when status is 'Idle'")
|
|
56
|
+
|
|
57
|
+
# Bottleneck must reflect actual vs target
|
|
58
|
+
expected_bottleneck = self.cycle_time_actual > self.cycle_time_target
|
|
59
|
+
if self.is_bottleneck != expected_bottleneck:
|
|
60
|
+
raise ValueError(
|
|
61
|
+
f"is_bottleneck must be {expected_bottleneck} "
|
|
62
|
+
f"(cycle_time_actual={self.cycle_time_actual} vs "
|
|
63
|
+
f"cycle_time_target={self.cycle_time_target})"
|
|
64
|
+
)
|
|
65
|
+
return self
|
|
66
|
+
|
|
67
|
+
class WorkstationCreate(Workstation):
|
|
68
|
+
pass
|
|
69
|
+
|
|
70
|
+
class WorkstationUpdate(BaseModel):
|
|
71
|
+
name: str
|
|
72
|
+
line_id: Optional[str] = None
|
|
73
|
+
stage_id: Optional[str] = None
|
|
74
|
+
mode: WorkstationMode
|
|
75
|
+
status: WorkstationStatus
|
|
76
|
+
description: Optional[str] = None
|
|
77
|
+
operator: Optional[str] = Field(None, description="Required for Manual and Hybrid modes")
|
|
78
|
+
cycle_time_actual: float = Field(..., ge=0, description="Actual cycle time in seconds")
|
|
79
|
+
cycle_time_target: float = Field(..., gt=0, description="Target cycle time in seconds")
|
|
80
|
+
is_bottleneck: bool = Field(..., description="True when cycle_time_actual exceeds cycle_time_target")
|
|
81
|
+
created_at: datetime = Field(default_factory=utc_now)
|
|
82
|
+
updated_at: datetime = Field(default_factory=utc_now)
|
|
83
|
+
|
|
84
|
+
@model_validator(mode="after")
|
|
85
|
+
def check_constraints(self) -> "WorkstationUpdate":
|
|
86
|
+
# Operator rules — only validate when both fields are present in the patch
|
|
87
|
+
if self.mode == "Robotic" and self.operator is not None:
|
|
88
|
+
raise ValueError("operator must be None when mode is 'Robotic'")
|
|
89
|
+
if self.mode in ("Manual", "Hybrid") and self.operator is not None and not self.operator:
|
|
90
|
+
raise ValueError(f"operator cannot be empty when mode is '{self.mode}'")
|
|
91
|
+
|
|
92
|
+
# Bottleneck consistency — only validate when all three fields are provided
|
|
93
|
+
if (
|
|
94
|
+
self.is_bottleneck is not None
|
|
95
|
+
and self.cycle_time_actual is not None
|
|
96
|
+
and self.cycle_time_target is not None
|
|
97
|
+
):
|
|
98
|
+
expected = self.cycle_time_actual > self.cycle_time_target
|
|
99
|
+
if self.is_bottleneck != expected:
|
|
100
|
+
raise ValueError(
|
|
101
|
+
f"is_bottleneck must be {expected} "
|
|
102
|
+
f"(cycle_time_actual={self.cycle_time_actual} vs "
|
|
103
|
+
f"cycle_time_target={self.cycle_time_target})"
|
|
104
|
+
)
|
|
105
|
+
return self
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
class WorkstationResponse(Workstation):
|
|
109
|
+
class Config:
|
|
110
|
+
from_attributes = True
|
|
111
|
+
|
|
112
|
+
|
|
113
|
+
class PaginatedWorkstationResponse(BaseModel):
|
|
114
|
+
total: int
|
|
115
|
+
page: int
|
|
116
|
+
page_size: int
|
|
117
|
+
results: list[WorkstationResponse]
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
from typing import List, Optional
|
|
2
|
+
from pydantic import BaseModel, Field
|
|
3
|
+
from services.events.models.events import Event
|
|
4
|
+
|
|
5
|
+
class WorkSrationLiveState(BaseModel):
|
|
6
|
+
# Unique Identifiers for the Location
|
|
7
|
+
node_id: str = Field(description="The UI canvas node ID, e.g., 'Work Station 1'")
|
|
8
|
+
work_station_id: Optional[str] = Field(None, description="Physical hardware identifier for the station")
|
|
9
|
+
|
|
10
|
+
# Order Tracking Context
|
|
11
|
+
work_order_id: Optional[str] = Field(None, description="The parent work order database ID")
|
|
12
|
+
order_number: Optional[str] = Field(None, description="The human-readable tracking number, e.g., 'WO-9941'")
|
|
13
|
+
order_status: str = Field("Idle", description="Live state: Idle, Setup, Running, Paused, Cleanup")
|
|
14
|
+
|
|
15
|
+
# Personnel Tracking (RFID/NFC Badge scans)
|
|
16
|
+
employee_id: Optional[str] = Field(None, description="The operator currently logged into this station")
|
|
17
|
+
work_station_id: Optional[str] = Field(None, description="Current workstation being tracked")
|
|
18
|
+
|
|
19
|
+
# Active Hardware & Tooling Ecosystem (Live RFID Detections)
|
|
20
|
+
active_machine_id: List[str] = Field(default_factory=list, description="Fixed machines assigned/connected")
|
|
21
|
+
active_equipment_id: List[str] = Field(default_factory=list, description="Mobile assets docked here, e.g., ['SS-BIN-01']")
|
|
22
|
+
active_device: Optional[str] = Field(None, description="Primary active handheld or test device connected")
|
|
23
|
+
|
|
24
|
+
# Bill of Materials (BOM) Expected Lists
|
|
25
|
+
component_list: List[str] = Field(default_factory=list, description="Target parts/components needed for this job")
|
|
26
|
+
raw_material_list: List[str] = Field(default_factory=list, description="Raw materials/lot batches required")
|
|
27
|
+
|
|
28
|
+
# Live Material Telemetry & Metrics (Real-time updates from scans)
|
|
29
|
+
active_component_count: List[int] = Field(default_factory=list, description="Current quantities of active components present")
|
|
30
|
+
active_rawmaterial_quantity: List[float] = Field(default_factory=list, description="Current mass/volume of raw materials remaining")
|
|
31
|
+
active_completed_product_count: int = Field(0, description="Running tally of finished pieces passing through this node")
|
|
32
|
+
|
|
33
|
+
# active scan events
|
|
34
|
+
|
|
35
|
+
# 1. user_scan_events: List[UserScanEvent]
|
|
36
|
+
# 2. machine_scan_events: List[Event]
|
|
37
|
+
# 3. equipment_scan_events: List[Event]
|
|
38
|
+
# 4. component_scan_event: List[ComponentScanEvent]
|
|
39
|
+
# 5. raw_material_scan_event: List[RawMaterialScanEvent]
|
|
40
|
+
# 6. completed_product_scan_event : List[CompletedProductScanEvent]
|
|
41
|
+
|
|
42
|
+
# Derived fields
|
|
43
|
+
# 1. remaining raw material
|
|
44
|
+
# 2. machine / equipment down time by workstation
|
|
45
|
+
# 2.1. down time due to cleaning
|
|
46
|
+
# 2.2. down time due to mainenance
|
|
47
|
+
# 2.3. down time due to calibtation
|
|
48
|
+
# 3. actual cycle time and tack time at station
|
|
49
|
+
# 4. scheduled time vs actual time taken for step
|
|
50
|
+
|
|
51
|
+
# Next Phase
|
|
52
|
+
# machine performance
|
|
53
|
+
# sensor readings
|
|
54
|
+
# readings from plc
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
|