teach/db/016_class_name_unique.sql
Ramon 6742e07363
All checks were successful
dev - build & deploy naar test / build-and-deploy (push) Successful in 35s
fix: altijd de echte serverfout tonen + klasnamen uniek per school (v0.4.1-beta)
- de generieke errorhandler gaf alleen detail mee als req.user al gezet was;
  bleek de fout zelf al vóór/tijdens dat moment te zitten (zoals bij klas
  verwijderen), dan bleef het toch de kale "serverfout" - nu altijd de echte
  oorzaak, dit is een intern beheertool zonder publieke bezoekers
- klasnamen konden onbeperkt dubbel aangemaakt worden binnen dezelfde school
  (geen enkele controle) - POST /admin/classes weigert dit nu met 409, en een
  nieuwe unieke index (school_id, lower(name)) is het echte vangnet
- migratie 016 hernoemt eerst bestaande dubbele klasnamen (niets verwijderd)
  vóórdat de unieke index wordt gezet: anders was de migratie zelf op deze
  database mislukt en had de app niet meer opgestart
2026-07-18 03:39:04 +02:00

28 lines
1.1 KiB
SQL

-- v0.4.1-beta: een klasnaam mag niet dubbel voorkomen binnen dezelfde school.
-- Zonder deze constraint kon "Nieuwe klas" herhaaldelijk dezelfde naam
-- aanmaken (bv. na een eerdere poging die door een andere bug leek te
-- mislukken, maar stiekem toch al aanmaakte) - de app-laag controleert dit nu
-- ook (POST /admin/classes), maar de database-constraint is het echte vangnet.
--
-- Bestaande dubbele klasnamen eerst uniek maken: anders faalt de CREATE
-- UNIQUE INDEX hieronder op een database die deze bug al heeft laten
-- ontstaan (en dan start de app helemaal niet meer op). Er wordt niets
-- verwijderd, alleen de latere dubbele naam hernoemd - de klas, z'n
-- leerlingen en koppelingen blijven ongemoeid.
DO $$
DECLARE
r RECORD;
BEGIN
FOR r IN
SELECT id, name,
ROW_NUMBER() OVER (PARTITION BY school_id, lower(name) ORDER BY id) AS rn
FROM classes
LOOP
IF r.rn > 1 THEN
UPDATE classes SET name = r.name || ' (' || r.rn || ')' WHERE id = r.id;
END IF;
END LOOP;
END $$;
CREATE UNIQUE INDEX IF NOT EXISTS idx_classes_school_name
ON classes (school_id, lower(name));