Problem
Obecnie 5 typów rekordów publikacji — Wydawnictwo_Ciagle,
Wydawnictwo_Zwarte, Praca_Doktorska, Praca_Habilitacyjna, Patent
— kasuje się fizycznie (DELETE). Skutki:
- bezpowrotna utrata danych (brak „kosza", brak undo),
- kaskadowe usunięcie powiązań autor↔rekord (
*_Autor),
- brak śladu audytowego.
Cel
Wprowadzić soft-delete: zamiast usuwać wiersz, ustawiamy znacznik
deleted_at. Rekord znika z widoku publicznego / ewaluacji / API, ale
dane (w tym powiązania *_Autor) zostają i można je przywrócić.
Kluczowe ustalenia (z rozpoznania)
- Choke-point = trigger
bpp_refresh_cache(): większość systemu czyta
przez materializowany Rekord. Wystarczy nauczyć trigger traktować
deleted_at IS NOT NULL jak DELETE → konsumenci Rekord/Cache_*
czyszczą się jednym ruchem.
django-soft-delete jest już w repo (precedens: zglos_publikacje).
Domyślny manager ukrywa usunięte → ekspozycja (API/dashboard/autocomplete)
czysta „za darmo"; miejsca import/dedup/PBN muszą jawnie użyć
global_objects (inaczej duplikaty przy re-imporcie).
- Kaskada/auto-undelete pakietu wymaga, by dzieci były
SoftDeleteModel
(strict=True) → rekomendacja: Projekt A (override delete(), dzieci
*_Autor nietknięte, cache/trigger odtwarza je przy restore).
Status
⛔ ODŁOŻONE — na razie. Spec wykonalności jest gotowy (~2–3 tyg.
nakładu), ale nie wchodzi teraz w realizację (priorytety: DSpace,
powiązania autorów). Issue dla śladu; start od triggera + rozstrzygnięcia
otwartych decyzji.
Pełna analiza: docs/superpowers/specs/2026-06-03-soft-delete-publikacje.md
(PR z samym specem towarzyszy temu issue).
Problem
Obecnie 5 typów rekordów publikacji —
Wydawnictwo_Ciagle,Wydawnictwo_Zwarte,Praca_Doktorska,Praca_Habilitacyjna,Patent— kasuje się fizycznie (
DELETE). Skutki:*_Autor),Cel
Wprowadzić soft-delete: zamiast usuwać wiersz, ustawiamy znacznik
deleted_at. Rekord znika z widoku publicznego / ewaluacji / API, aledane (w tym powiązania
*_Autor) zostają i można je przywrócić.Kluczowe ustalenia (z rozpoznania)
bpp_refresh_cache(): większość systemu czytaprzez materializowany
Rekord. Wystarczy nauczyć trigger traktowaćdeleted_at IS NOT NULLjakDELETE→ konsumenciRekord/Cache_*czyszczą się jednym ruchem.
django-soft-deletejest już w repo (precedens:zglos_publikacje).Domyślny manager ukrywa usunięte → ekspozycja (API/dashboard/autocomplete)
czysta „za darmo"; miejsca import/dedup/PBN muszą jawnie użyć
global_objects(inaczej duplikaty przy re-imporcie).SoftDeleteModel(
strict=True) → rekomendacja: Projekt A (overridedelete(), dzieci*_Autornietknięte, cache/trigger odtwarza je przy restore).Status
⛔ ODŁOŻONE — na razie. Spec wykonalności jest gotowy (~2–3 tyg.
nakładu), ale nie wchodzi teraz w realizację (priorytety: DSpace,
powiązania autorów). Issue dla śladu; start od triggera + rozstrzygnięcia
otwartych decyzji.
Pełna analiza:
docs/superpowers/specs/2026-06-03-soft-delete-publikacje.md(PR z samym specem towarzyszy temu issue).