Develop#48
Merged
Merged
Conversation
…/timed/full) - Add system settings: production_qty_edit_policy (none/timed/full) + time window in minutes - Settings UI: radio cards in Production tab with conditional time window input - ProductionCorrectionController: edit/update with policy enforcement + audit logging - Workstation view: pencil icon on shift entries (auto-hides after timed window expires) - Correction form: shows order, product, shift, current qty, input for new qty - Recalculates work order produced_qty from all shift entries after correction - Polish translations for all new strings
…to prevent WO disappearing on line change
…nstead of overlapping
…Types, Lines; add Settings export - Import button + ? icon (example CSV download) on Materials, Product Types, Lines index pages - ImportExampleController serves example CSV files per entity type - Settings → Data → Export Settings button downloads all system_settings as JSON - Polish translations for all new strings
- Import Settings section in Settings → Data tab - Upload previously exported JSON, overwrites current settings - Forbidden keys blacklist (db credentials, app_key) — never imported - Only string/numeric values accepted, non-scalar silently skipped - Cache flush after import - Polish translations
…ings import CRITICAL: - ProductionCorrectionController: add ownership check — operators can only correct their own entries, Supervisor/Admin can correct any MEDIUM: - Settings import: expanded forbidden keys (app_debug, cors, reverb, mail, modules_enabled) - Settings import: only update existing keys — no arbitrary key injection - Settings import: max value length 1000 chars
…T/POST only, no preflight cache - Default cors_allowed_origins: empty (block all cross-origin) instead of * (allow all) - Added cors_allowed_methods setting (default: GET, POST) - Added cors_max_age setting (default: 0 — no preflight caching) - Middleware reads all 3 CORS settings from DB - Empty origins = no CORS headers sent (most restrictive) - Non-matching origin = no CORS headers (fail-closed) - Polish translations
…ls, shifts, ISA-95, and more - Export: dumps 21 config tables + system_settings to JSON (no production data, no users) - Import: truncate + re-insert for config tables, key-value update for system_settings - Backward compatible with old settings-only format - DB transaction for atomicity, rollback on error - Skips id/created_at/updated_at/tenant_id on import - Max file size 10MB - Updated UI descriptions and Polish translations
…ations with production data
…d unique keys for more tables
… polling with alert sound - AlertController: add nonBlockingIssues to view, totalCount includes all open issues - New /alerts/check endpoint for JSON polling - Alerts page polls every 5 seconds for new issues - Red banner with pulse animation when new alert detected - Triple beep sound (880Hz square wave) on new alert - Non-blocking issues shown in separate table below grid - Live indicator in header
…ews) - Load pending/in_progress maintenance events in date range - Weekly view: purple blocks with wrench icon below WO bars - Hourly Gantt: purple 1h blocks at bottom of lane - planner-weeks partial: same pattern for infinite scroll
…rt and end time on planner - Migration: add scheduled_end_at column to maintenance_events - Model: add to fillable + casts - Controller: validate scheduled_end_at (after scheduled_at) on create/update - Form: side-by-side "Scheduled start" + "Scheduled end" datetime inputs - Hourly Gantt: use actual duration (end-start) instead of fixed 1h block - Seeder: updated with scheduled_end_at, moved pending events to today/tomorrow for visibility
…(24px→36px, bolder text)
…rly Gantt (bg-purple-200, shadow, top instead of bottom)
…ument order was reversed
…chedules (not just existing events)
…ble range (weekly shows every week, not just next_due)
…s, operators, admins) - MaintenanceReminder Blade component — shows pending maintenance due within 2 hours - Fixed purple popup in bottom-right corner with chime sound (C5+E5 two-tone) - Polls every 30 seconds for new maintenance events - Dismissible — X button hides until page reload - Added to global app layout (visible on all pages for all authenticated users) - Polling endpoint /maintenance/upcoming-count for all authenticated users - Polish translation
…ction view Operator queue and workstation views now auto-refresh every 5 seconds when work order state changes (step completion, quantity update). This enables seamless product transitions between workstations — when one operator completes a step, the next operator's view updates automatically. Added JSON check endpoints: - GET /operator/queue/check — returns active WO count + workstation queue count - GET /operator/workstation/check — returns hash of WO states for change detection
Phase 1 implementation: - TOTP setup with QR code (endroid/qr-code + pragmarx/google2fa) - 6-digit code verification with +-30s window - 8 one-time recovery codes (bcrypt hashed, encrypted at rest) - Login challenge page with auto-submit on 6 digits - Rate limit: 5 attempts/min on challenge - Enable/disable 2FA from Profile (password required to disable) - Regenerate recovery codes (password required) - Fix broken HTML tags in profile view
…wn station
Adds an optional "Workstation routing" mode. When enabled, a workstation-bound
operator may only start/complete steps assigned to their own workstation; work
passes from one station to the next as steps are completed. Supervisors, admins
and line-level operators (no workstation assigned) are not restricted.
- New setting workstation_routing_enabled (Production Rules) — off by default
- Server-side guard in BatchService::guardWorkstationRouting() — single
chokepoint covering both the Livewire UI and the REST API
- Livewire step list locks steps belonging to other stations ("Other station")
- Operator queue auto-selects a workstation account's own station and, when
routing is on, surfaces incoming work routed across lines (e.g. shared packing)
- Feature tests cover own/other station, admin bypass, line operator, routing
off, and steps without an assigned workstation
Adds full Turkish translation (1253/1253 strings) keyed by English source
strings, preserving English-first: English remains the source and fallback,
Turkish overrides only where translated.
- lang/tr.json — complete UI translation (1253 keys, 100% coverage)
- lang/tr/{auth,pagination,passwords,validation}.php — framework messages
- Register 'tr' => 'Türkçe' in AppServiceProvider::availableLocales()
- Allow 'tr' in the language setting validation
- Language selector auto-discovers the new locale (no hardcoding)
83 strings reuse human-verified translations from the original community
contribution; the remaining ~1170 are machine translations and would benefit
from a native-speaker review pass.
feat(i18n): add Turkish (Türkçe) as a third UI language
…eline Adds full Modbus TCP support and the protocol-agnostic core that all machine protocols feed through (MQTT already existed; OPC UA gateway is the next phase). Foundation (Phase 0): - machine_tags: protocol-agnostic tag → signal mapping with transforms (scale/offset/value-map) - workstation_states: time-sliced machine state timeline - machine_events: append-only event store (correlation id, microsecond ts, synced_to_cloud for edge sync) - MachineSignalIngestor: single entry point routing state/counter/telemetry/ alarm signals - WorkstationStateMachine: state transitions + automatic ProductionDowntime on STOPPED/FAULT (auto-provisioned reasons) Modbus TCP (Phase 1): - aldas/modbus-tcp-client; modbus_connections config - ModbusReader (int16/uint16/int32/float32/bool, endianness, Modicon addresses) - modbus:poll daemon (per-connection, reconnect/backoff) - modbus:simulate — in-PHP Modbus TCP server simulating a machine (state cycle + counters + telemetry) for end-to-end testing without hardware - Admin → Connectivity → Modbus CRUD + tag editor Value loop (Phase 3) + monitor (Phase 4): - Auto-downtime from machine states; per-workstation availability/quality - MachineMonitorService + live Machine Monitor (polling tiles) OPC UA (Phase 2): opcua_connections schema scaffolded; the gateway sidecar that bridges OPC UA → MQTT is the remaining infra-heavy piece. Verified end-to-end on the test instance: simulator → real Modbus poller → ingestor → state machine → auto-downtime → per-workstation OEE → live monitor (RUNNING/FAULT/IDLE timeline, availability 85%, quality 93%). Tests: 8 feature/unit tests (transforms, state machine, auto-downtime, counter deltas, monitor, Modbus address normalization).
OPC UA support via a gateway sidecar, plus a runtime-status layer that tells users — in the UI — when a connection is configured but its required daemon / container is not running (important for non-Docker deployments). OPC UA (Phase 2): - opcua_connections CRUD (Admin → Connectivity → OPC UA) + node/tag editor - MachineGatewayController: gateway-config, signals (ingest), heartbeat APIs — protocol-agnostic, reusable by any external REST gateway - opcua-gateway/ Node.js sidecar (node-opcua): subscribes to OPC UA nodes and forwards readings to the ingest API; flows through the same pipeline as Modbus/MQTT (state machine, auto-downtime, OEE, monitor) - Dockerfile + README + docker-compose service (opt-in connectivity profile) Runtime health awareness: - RuntimeMonitor: heartbeat per connection; daemons/gateways mark themselves alive each cycle - Modbus poller emits heartbeat; gateway posting counts as heartbeat - _runtime-status partial: green "running (last seen Ns ago)" or amber "not running" with copy-paste start commands (bare metal + Docker) - Shown on Modbus and OPC UA connection pages Infra (docker-compose, all opt-in profiles): - modbus-poller, opcua-gateway (connectivity profile) - queue-worker (workers profile) — for MQTT/queued jobs in production Verified end-to-end on test instance: Modbus runtime banner flips not-running→running; OPC UA gateway config + ingest drives RUNNING→FAULT + auto-downtime + heartbeat, all visible in the UI. Tests: +5 (runtime monitor, start instructions, gateway config/ingest, node-id resolution). Suite green apart from pre-existing unrelated failures.
…onale for contributors
…ge conflict The develop merge conflict resolution in pl.json kept the develop side and dropped the 82 print-labels/packaging keys, leaving the packaging station, scanner config, EAN management and label-template editor untranslated (English fallback) for Polish users. Re-add the missing keys. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…-develop # Conflicts: # backend/lang/pl.json # backend/resources/views/packaging/admin.blade.php # backend/resources/views/packaging/eans/index.blade.php # backend/resources/views/packaging/station.blade.php
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Security & Auth
codes (encrypted/bcrypt), login challenge, rate limiting, enable/disable with
password ([feat] Two-Factor Authentication (2FA) — TOTP with QR code and recovery codes #41)
assigned to their own workstation; single server-side guard in
BatchServicecovering both Livewire UI and REST API
GET/POST only), ownership checks on production corrections, settings-import
whitelist
Machine Connectivity (new)
machine_tags->MachineSignalIngestor->
WorkstationStatemachine -> auto-downtime -> per-workstation OEE -> LiveMachine Monitor
aldas/modbus-tcp-client), poller daemon,in-PHP simulator (
modbus:simulate), CRUD + tag editor ([feat] Modbus TCP connector — legacy machine communication #24)opcua-gateway/, Node.js node-opcua) bridging to aprotocol-agnostic ingest API; CRUD + node editor ([feat] OPC UA connector — industrial machine communication #23)
is running, with copy-paste start commands (bare metal + Docker)
docker-composeservices:modbus-poller,opcua-gateway,queue-workerMaterial Traceability / Genealogy
material_lots.source_batch_id)LOT / material lot / supplier LOT / serial number
serial_units+unit_step_historywithparameter snapshots + API
Internationalization
preserved) (feat(i18n): add Turkish (Türkçe) as a third UI language #44)
Schedule & Maintenance
across the full visible range;
scheduled_end_at(start + end)change
Operations
stations automatically)
materials, shifts, ISA-95… — upsert-based to preserve FK relations, with a
forbidden-keys whitelist
Docs
docs/machine-connectivity.md— signal pipeline, protocols, "how to add a newprotocol", and intentionally-deferred items (Reverb, write-back, real-server
OPC UA test) with rationale
Testing
machine signal pipeline, gateway/runtime). Suite green apart from pre-existing
unrelated failures.
Merge notes
maincarries 17 commits develop lacks(fix(packaging): replace hardcoded Polish strings with __() translations #43 packaging i18n fix, AGPL-3.0 license switch, version bumps). Expect
conflicts in
lang/pl.json,packaging/*.blade.php,composer.json.