Adds src/helper/formatters/frostFormatter.js — structured-envelope formatter parallel to the InfluxDB one. Produces dbase messages that a CoreSync collector can forward to FROST/SensorThings without coupling producing nodes to FROST HTTP details. Registered in formatters/index.js.
Config additions in 4 node schemas (machineGroupControl, measurement, pumpingStation, rotatingMachine) expose the new dbase format option in the editor.
Part of the CoreSync FROST handoff initiative — see superproject CORESYNC_FROST_INTERVIEW_HANDOFF.md.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
outputUtils.formatMsg: fall back to \`<softwareType>_<id>\` when
config.general.name is unset — restores the convention the original
test expected; safer for nodes whose name isn't required at registration.
collectionValidators.validateArray + validateSet: replace \`|| 1\` with
\`?? 1\` so explicit minLength: 0 lets through empty arrays. Was
swallowing the 0 as falsy and clamping minimum to 1.
validationUtils: add public validateCurve wrapper around the helper so
callers can validate raw curves without going through validateSchema.
Test suite: 170 total / 170 pass (was 4 fail).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The MGC and pumpingStation registerChild handlers dispatch on
softwareType === 'machine' / 'machinegroup' / 'pumpingstation' /
'measurement'. But buildConfig sets functionality.softwareType to the
lowercased node name, so in production rotatingMachine reports
'rotatingmachine' and machineGroupControl reports 'machinegroupcontrol'.
Result: the MGC <-> rotatingMachine and pumpingStation <-> MGC wiring
silently never hit the right branch in production, even though every
unit test passes (tests pass an already-aliased softwareType manually).
Fix: tiny SOFTWARE_TYPE_ALIASES map at the central registerChild
dispatcher in childRegistrationUtils. Real production names get
translated to the dispatch keys parents already check for, while tests
that pass already-aliased keys are unaffected (their values aren't in
the alias map and pass through unchanged).
rotatingmachine -> machine
machinegroupcontrol -> machinegroup
Verified end-to-end on Dockerized Node-RED: MGC now reports
'3 machine(s) connected' when wired to 3 rotatingMachine ports;
pumpingStation registers MGC as a machinegroup child and listens to
its predicted-flow stream.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
migrateConfig stamps a version string into config schemas. validateSchema
then iterates the string's character indices, causing infinite recursion.
Skip the 'version' key and guard against any non-object schema entries.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
ConfigManager.migrateConfig() was called but never defined — would crash at runtime.
Added config version checking, migration support, and fixed createEndpoint indentation.
New formatters module (csv, influxdb, json) for pluggable output formatting.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Replace hardcoded position strings with POSITIONS.* constants
- Prefix unused variables with _ to resolve no-unused-vars warnings
- Fix no-prototype-builtins with Object.prototype.hasOwnProperty.call()
- Extract menuUtils.js (543 lines) into 6 focused modules under menu/
- menuUtils.js now 35 lines, delegates via prototype mixin pattern
- Add 158 unit tests for ConfigManager, MeasurementContainer, ValidationUtils
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Break the 548-line monolith into focused modules:
- validators/typeValidators.js (number, integer, boolean, string, enum)
- validators/collectionValidators.js (array, set, object)
- validators/curveValidator.js (curve, machineCurve, dimensionStructure)
validationUtils.js now uses a VALIDATORS registry map and delegates to
extracted modules. Reduced from 548 to 217 lines.
Closes#2
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- ConfigManager.buildConfig() now lowercases softwareType
- Updated config JSON defaults to lowercase
- childRegistrationUtils lowercases softwareType on extraction
- Closes#8
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>