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:
@@ -0,0 +1,46 @@
|
||||
-- Folgezähler-Kette: Meter zeigt optional auf den Vorgänger.
|
||||
-- Beim Wechsel können wir dann sowohl die Kette für die UI anzeigen
|
||||
-- als auch alle Verträge mit dem Vorgänger automatisch auf den
|
||||
-- Nachfolger umstellen.
|
||||
--
|
||||
-- ON DELETE SET NULL, damit ein versehentlich gelöschter Vorgänger
|
||||
-- den Nachfolger nicht killt.
|
||||
--
|
||||
-- IF NOT EXISTS macht den Re-Deploy auf Prod sicher, falls jemand
|
||||
-- schon `prisma db push` gefahren hat.
|
||||
|
||||
ALTER TABLE `Meter`
|
||||
ADD COLUMN IF NOT EXISTS `predecessorMeterId` INT NULL;
|
||||
|
||||
-- Index nur anlegen, wenn er noch nicht da ist
|
||||
SET @idx_exists := (
|
||||
SELECT COUNT(*) FROM information_schema.STATISTICS
|
||||
WHERE TABLE_SCHEMA = DATABASE()
|
||||
AND TABLE_NAME = 'Meter'
|
||||
AND INDEX_NAME = 'Meter_predecessorMeterId_fkey'
|
||||
);
|
||||
SET @sql := IF(
|
||||
@idx_exists = 0,
|
||||
'CREATE INDEX `Meter_predecessorMeterId_fkey` ON `Meter`(`predecessorMeterId`)',
|
||||
'SELECT "Index existiert bereits"'
|
||||
);
|
||||
PREPARE stmt FROM @sql;
|
||||
EXECUTE stmt;
|
||||
DEALLOCATE PREPARE stmt;
|
||||
|
||||
-- Foreign Key nur anlegen, wenn er noch nicht da ist
|
||||
SET @fk_exists := (
|
||||
SELECT COUNT(*) FROM information_schema.TABLE_CONSTRAINTS
|
||||
WHERE TABLE_SCHEMA = DATABASE()
|
||||
AND TABLE_NAME = 'Meter'
|
||||
AND CONSTRAINT_NAME = 'Meter_predecessorMeterId_fkey'
|
||||
AND CONSTRAINT_TYPE = 'FOREIGN KEY'
|
||||
);
|
||||
SET @sql := IF(
|
||||
@fk_exists = 0,
|
||||
'ALTER TABLE `Meter` ADD CONSTRAINT `Meter_predecessorMeterId_fkey` FOREIGN KEY (`predecessorMeterId`) REFERENCES `Meter`(`id`) ON DELETE SET NULL ON UPDATE CASCADE',
|
||||
'SELECT "FK existiert bereits"'
|
||||
);
|
||||
PREPARE stmt FROM @sql;
|
||||
EXECUTE stmt;
|
||||
DEALLOCATE PREPARE stmt;
|
||||
@@ -489,6 +489,12 @@ model Meter {
|
||||
tariffModel MeterTariffModel @default(SINGLE) // Eintarif oder Zweitarif (HT/NT)
|
||||
location String?
|
||||
isActive Boolean @default(true)
|
||||
// Folgezähler-Kette: zeigt auf den Vorgänger, den dieser Zähler abgelöst hat.
|
||||
// Wird beim Anlegen als Folgezähler gesetzt; informational + zum Anzeigen
|
||||
// der Kette. Auto-Propagation auf Verträge passiert beim Create.
|
||||
predecessorMeterId Int?
|
||||
predecessor Meter? @relation("MeterSuccessor", fields: [predecessorMeterId], references: [id], onDelete: SetNull)
|
||||
successors Meter[] @relation("MeterSuccessor")
|
||||
readings MeterReading[]
|
||||
energyDetails EnergyContractDetails[]
|
||||
contractMeters ContractMeter[] @relation("ContractMeters")
|
||||
|
||||
Reference in New Issue
Block a user