Folgezähler-Deklaration in der Kundenakte (Auto-Propagation)

- Meter.predecessorMeterId (Self-Relation) + Migration
  20260530140000_meter_predecessor mit IF NOT EXISTS
- createMeter akzeptiert optional successorOf:
  {predecessorMeterId, installedAt?, finalReadingPrevious?}.
  Vorgänger wird validiert (gleicher Kunde + Typ); alle Verträge
  mit dem Vorgänger als aktuellen Zähler werden analog zu
  addSuccessorMeter automatisch auf den neuen Zähler umgestellt
  (ContractMeter-Eintrag mit removedAt/finalReading für den
  Vorgänger, neuer ContractMeter mit installedAt + nächster
  Position, energyDetails.meterId aktualisiert)
- MeterModal: Checkbox "Als Folgezähler deklarieren" + Dropdown
  Vorgänger + Wechseldatum + Endstand. Typ/Tarifmodell/Adresse
  werden vom Vorgänger übernommen und disabled. Info-Banner über
  Vertragsauto-Update

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-05-30 13:48:23 +02:00
parent 6f378d750c
commit ad4c2bae1d
6 changed files with 278 additions and 5 deletions
@@ -603,10 +603,13 @@ export async function createMeter(req: AuthRequest, res: Response): Promise<void
const customerId = parseInt(req.params.customerId);
if (!(await canAccessCustomer(req, res, customerId))) return;
const meter = await customerService.createMeter(customerId, req.body);
const successorLabel = meter.predecessor
? ` als Folgezähler von ${meter.predecessor.meterNumber}`
: '';
await logChange({
req, action: 'CREATE', resourceType: 'Meter',
resourceId: meter.id.toString(),
label: `Zähler angelegt für Kunde #${customerId}`,
label: `Zähler angelegt${successorLabel} für Kunde #${customerId}`,
customerId,
});
res.status(201).json({ success: true, data: meter } as ApiResponse);