Skip to content

Develop#48

Merged
jakub-przepiora merged 41 commits into
mainfrom
develop
May 30, 2026
Merged

Develop#48
jakub-przepiora merged 41 commits into
mainfrom
develop

Conversation

@jakub-przepiora
Copy link
Copy Markdown
Contributor

Summary

Security & Auth

  • Two-Factor Authentication (2FA) — TOTP with QR setup, 8 one-time recovery
    codes (encrypted/bcrypt), login challenge, rate limiting, enable/disable with
    password ([feat] Two-Factor Authentication (2FA) — TOTP with QR code and recovery codes #41)
  • Workstation routing — optional mode restricting each operator to steps
    assigned to their own workstation; single server-side guard in BatchService
    covering both Livewire UI and REST API
  • Security hardening — fail-closed CORS defaults (empty origins block all,
    GET/POST only), ownership checks on production corrections, settings-import
    whitelist

Machine Connectivity (new)

  • Protocol-agnostic signal pipeline — machine_tags -> MachineSignalIngestor
    -> WorkstationState machine -> auto-downtime -> per-workstation OEE -> Live
    Machine Monitor
  • Modbus TCP — full implementation (aldas/modbus-tcp-client), poller daemon,
    in-PHP simulator (modbus:simulate), CRUD + tag editor ([feat] Modbus TCP connector — legacy machine communication #24)
  • OPC UA — gateway sidecar (opcua-gateway/, Node.js node-opcua) bridging to a
    protocol-agnostic ingest API; CRUD + node editor ([feat] OPC UA connector — industrial machine communication #23)
  • Runtime health awareness — UI shows whether each connection's daemon/container
    is running, with copy-paste start commands (bare metal + Docker)
  • Opt-in docker-compose services: modbus-poller, opcua-gateway,
    queue-worker

Material Traceability / Genealogy

  • Formal batch-output -> input-lot link (material_lots.source_batch_id)
  • Traceability console — recall-readiness: backward/forward trace by finished
    LOT / material lot / supplier LOT / serial number
  • Per-unit (serial) tracking — serial_units + unit_step_history with
    parameter snapshots + API

Internationalization

Schedule & Maintenance

  • Maintenance events on planner (weekly + hourly Gantt), incl. recurring blocks
    across the full visible range; scheduled_end_at (start + end)
  • Lane stacking for overlapping WOs; drag-and-drop no longer drops WOs on line
    change
  • Maintenance reminder popup with sound for supervisors & operators

Operations

  • Real-time polling for operator queue/workstation views (product flows between
    stations automatically)
  • Alerts show all open issues (not just blocking) with real-time polling + sound
  • Production quantity correction with configurable edit policy (none/timed/full)
  • Full configuration export/import (JSON) — lines, products, templates,
    materials, shifts, ISA-95… — upsert-based to preserve FK relations, with a
    forbidden-keys whitelist
  • Import buttons + example CSV downloads on Materials / Product Types / Lines

Docs

  • docs/machine-connectivity.md — signal pipeline, protocols, "how to add a new
    protocol", and intentionally-deferred items (Reverb, write-back, real-server
    OPC UA test) with rationale

Testing

  • New feature tests across all modules (2FA, workstation routing, traceability,
    machine signal pipeline, gateway/runtime). Suite green apart from pre-existing
    unrelated failures.

Merge notes

jakubprzepiora-cyber and others added 30 commits May 26, 2026 17:01
…/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
…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
… 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
…rly Gantt (bg-purple-200, shadow, top instead of bottom)
…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
jakubprzepiora-cyber and others added 11 commits May 29, 2026 08:56
…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.
…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
@jakub-przepiora jakub-przepiora merged commit 963bc74 into main May 30, 2026
1 check failed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants