-- =========================================================================== -- Die Leichen im Scheinprojekt "default" aufraeumen -- -- Bugtracker #382 / #387. Bis 2.8.0 legte POST /report eine Meldung ohne -- project_slug im Projekt "default" ab. Das ist kein Projekt: Es hat keine -- Zeile in dc_projects, also blieb project_id NULL. Die Items sind seitdem -- -- * in keiner Projektansicht sichtbar (die Auswahl kennt nur echte Projekte), -- * ueber die API nicht mehr erreichbar - dasselbe Token, das sie angelegt -- hat, bekommt 403 project_forbidden, weil es an sein eigenes Projekt -- gebunden ist, -- * und aus dem WebUI nicht loeschbar, weil es dort keine Loeschfunktion -- fuer Items gibt. -- -- Ab 2.8.1 entsteht nichts Neues mehr dieser Art: Ohne Slug gilt das -- Heimatprojekt des Tokens, und ohne beides gibt es eine Absage statt eines -- Ratens. Dieses Skript raeumt nur den Altbestand. -- -- --------------------------------------------------------------------------- -- NICHT AUTOMATISCH AUSGEFUEHRT. Es liegt bewusst NICHT in sql/migrations/ - -- dort wird jede .sql beim Start angewendet (siehe Core\Migrator), und ein -- DELETE gehoert nicht in einen Vorgang, der ungefragt laeuft. -- -- Von Hand, Abschnitt fuer Abschnitt, und Abschnitt 1 zuerst. -- --------------------------------------------------------------------------- -- -- Achtung beim Loeschen: bugtracker_comments und bugtracker_item_affects -- haengen mit ON DELETE CASCADE an den Items. Was hier faellt, nimmt seine -- Kommentare und Betroffenenvermerke mit. -- =========================================================================== -- --------------------------------------------------------------------------- -- 1. ANSEHEN. Was liegt ueberhaupt dort? -- --------------------------------------------------------------------------- -- created_by ist die einzige verlaessliche Spur, wem ein Item gehoert: -- reported_from blieb bei genau diesen Meldungen leer. Grund war die -- Reihenfolge im alten Code - "Fremdmeldung?" wurde am mitgeschickten Slug -- entschieden, und der fehlte ja gerade. Deshalb griff weder die -- Begruendungspflicht noch der Fremdmeldungs-Eingang. SELECT id, created_by, reported_from, type, severity, status, build_version, created_at, LEFT(title, 70) AS titel FROM bugtracker_items WHERE project_slug = 'default' ORDER BY id; -- Wer hat wie viel dort abgelegt? Das ist die Grundlage fuer Abschnitt 2: -- Ein created_by, das eindeutig zu einem Projekt gehoert, laesst sich -- umhaengen. Ein gemischtes nicht. SELECT created_by, COUNT(*) AS anzahl, MIN(id) AS von, MAX(id) AS bis FROM bugtracker_items WHERE project_slug = 'default' GROUP BY created_by ORDER BY anzahl DESC; -- Gegenprobe: Gibt es "default" womoeglich doch als Projekt? Wenn diese -- Abfrage eine Zeile liefert, ist die Lage eine andere als hier beschrieben - -- dann bitte erst klaeren, wer es wann angelegt hat. SELECT * FROM dc_projects WHERE slug = 'default'; -- --------------------------------------------------------------------------- -- BEFUND VOM 31.08.2026 - der Bestand ist aufgenommen -- --------------------------------------------------------------------------- -- Es sind 20 Items. created_by ordnet sie eindeutig zu, und JEDES hat einen -- titelgleichen Zwilling im richtigen Projekt: -- -- clawddotnet 352, 353, 365, 366, 368, 369, 370 -> #373-#379 -- ibkrtrader 355, 356, 357, 358, 359, 360, -- 361, 362, 367 -> #388-#396 -- polytrader 371, 372, 380, 381 -> #383-#386 -- -- An jedem Original haengt genau EIN Kommentar: der automatische -- Erfassungsvermerk ("Bug im System erfasst."). Es gibt also keine Historie, -- die beim Loeschen verlorenginge - der Abgleich in Abschnitt 1 sollte das -- vor dem Loeschen trotzdem noch einmal bestaetigen, denn seither kann -- jemand kommentiert haben. -- -- Deshalb ist Abschnitt 3 (loeschen) hier der richtige Weg und Abschnitt 2 -- (umhaengen) nur die Rueckfallebene, falls der Abgleich etwas anderes zeigt. -- --------------------------------------------------------------------------- -- 2. UMHAENGEN statt loeschen - die Rueckfallebene. -- --------------------------------------------------------------------------- -- Zu benutzen, wenn an einem Item doch etwas haengt, das in der Neuablage -- fehlt. Dann waere allerdings der Zwilling zu loeschen, sonst steht derselbe -- Befund zweimal im Projekt. -- UPDATE bugtracker_items -- SET project_slug = 'clawddotnet', -- project_id = (SELECT id FROM dc_projects WHERE slug = 'clawddotnet') -- WHERE project_slug = 'default' -- AND id IN (352, 353, 365, 366, 368, 369, 370); -- UPDATE bugtracker_items -- SET project_slug = 'ibkrtrader', -- project_id = (SELECT id FROM dc_projects WHERE slug = 'ibkrtrader') -- WHERE project_slug = 'default' -- AND id IN (355, 356, 357, 358, 359, 360, 361, 362, 367); -- UPDATE bugtracker_items -- SET project_slug = 'polytrader', -- project_id = (SELECT id FROM dc_projects WHERE slug = 'polytrader') -- WHERE project_slug = 'default' -- AND id IN (371, 372, 380, 381); -- --------------------------------------------------------------------------- -- 3. LOESCHEN - der vorgesehene Weg. -- --------------------------------------------------------------------------- -- Der Inhalt steht vollstaendig im jeweils richtigen Projekt (siehe Befund -- oben). Die Altablage ist reiner Ballast: unsichtbar, unerreichbar, und sie -- verfaelscht jede Zaehlung ueber alle Projekte. -- -- Erst zaehlen. Kommt hier nicht 20 heraus, hat sich der Bestand seit dem -- 31.08.2026 geaendert - dann zurueck zu Abschnitt 1. -- SELECT COUNT(*) AS wird_geloescht -- FROM bugtracker_items -- WHERE project_slug = 'default' -- AND id IN (352, 353, 355, 356, 357, 358, 359, 360, 361, 362, -- 365, 366, 367, 368, 369, 370, 371, 372, 380, 381); -- Sicherungskopie, falls die Zuordnung spaeter doch noch gebraucht wird. -- Kostet nichts und macht den Schritt umkehrbar. -- CREATE TABLE bugtracker_items_default_backup_20260831 AS -- SELECT * FROM bugtracker_items WHERE project_slug = 'default'; -- DELETE FROM bugtracker_items -- WHERE project_slug = 'default' -- AND id IN (352, 353, 355, 356, 357, 358, 359, 360, 361, 362, -- 365, 366, 367, 368, 369, 370, 371, 372, 380, 381); -- --------------------------------------------------------------------------- -- 4. NACHSEHEN. Sollte 0 liefern, wenn alles umgehaengt oder geloescht ist. -- --------------------------------------------------------------------------- -- SELECT COUNT(*) AS noch_in_default -- FROM bugtracker_items -- WHERE project_slug = 'default'; -- --------------------------------------------------------------------------- -- 5. Gibt es weitere verwaiste Slugs? -- --------------------------------------------------------------------------- -- "default" war die haeufigste Falltuer, aber nicht die einzige moegliche: -- Ein Tippfehler im project_slug wurde bis 2.8.0 ebenso klaglos angenommen. -- Ab 2.8.1 weist der Endpunkt ein unbekanntes Projekt mit 400 unknown_project -- ab; der Altbestand bleibt davon unberuehrt. SELECT b.project_slug, COUNT(*) AS anzahl, MIN(b.created_at) AS aeltestes, MAX(b.created_at) AS juengstes FROM bugtracker_items b LEFT JOIN dc_projects p ON p.slug = b.project_slug WHERE p.id IS NULL GROUP BY b.project_slug ORDER BY anzahl DESC;