diff --git a/src/active/activeState.js b/src/active/activeState.js index a9225da..fb5cbef 100644 --- a/src/active/activeState.js +++ b/src/active/activeState.js @@ -10,6 +10,7 @@ */ const store = require('../store/fileStore'); const units = require('../gcode/units'); +const cfg = require('../config'); const { ApiError } = require('../errors'); class ActiveState { @@ -114,9 +115,10 @@ class ActiveState { // ---- Teaching / Editieren (persistiert) ---- - /** Hängt die aktuelle Pose als G-Code-Zeile an (FPoint). pose: a/b/c/e in RADIAN. */ + /** Hängt die aktuelle Pose als G-Code-Zeile an (FPoint). pose: a/b/c/e in RADIAN. + * Kein aktives Programm → Default-Programm auto-laden (backward-compat. mit log.gcode). */ async appendPoint(pose, feedrate) { - this._requireActive(); + if (!this.programId) await this.load(cfg.defaultProgramId); if (!pose) throw new ApiError(400, 'FILE_ERROR', 'pose required'); const line = units.formatPointLine(pose, feedrate); this.lines.push(line); diff --git a/src/config.js b/src/config.js index f4dfcdc..f28a4d6 100644 --- a/src/config.js +++ b/src/config.js @@ -14,4 +14,7 @@ module.exports = { // Optionaler Bearer-Token für schreibende Endpoints. // Fehlt er, sind Schreibzugriffe offen (Dev-Modus). apiKey: process.env.FILE_API_KEY || null, + // Default-Programm, das bei FPoint automatisch geladen wird wenn keines aktiv ist. + // Entspricht dem alten Verhalten (GCodeFiles/log.gcode immer implizit aktiv). + defaultProgramId: process.env.DEFAULT_PROGRAM_ID || 'log', }; diff --git a/test/activeState.test.js b/test/activeState.test.js index e44bb4c..b2c66ff 100644 --- a/test/activeState.test.js +++ b/test/activeState.test.js @@ -71,10 +71,15 @@ test('Cursor wird beim Speichern als !-Kommentar abgelegt (genau eine Zeile)', a expect(units.splitComment(marked[0]).code).toBe('G4 P0.1'); }); -test('Aktion ohne aktives Programm → NO_ACTIVE_PROGRAM', async () => { +test('Stepping ohne aktives Programm → NO_ACTIVE_PROGRAM', async () => { const a = new ActiveState(); expect(() => a.next()).toThrow(); // NO_ACTIVE_PROGRAM - await expect(a.appendPoint({ x: 0, y: 0, z: 0, a: 0, b: 0, c: 0, e: 0 })).rejects.toMatchObject({ - code: 'NO_ACTIVE_PROGRAM', - }); +}); + +test('FPoint ohne aktives Programm → auto-lädt Default-Programm (log)', async () => { + const a = new ActiveState(); + // appendPoint lädt automatisch das Default-Programm und legt es leer an + const r = await a.appendPoint({ x: 0, y: 0, z: 0, a: 0, b: 0, c: 0, e: 0 }); + expect(r.index).toBe(0); + expect(a.programId).toBeTruthy(); // Default-Programm wurde geladen });