Skip to content

docs(historia-zmian): spec wersjonowania zmian (django-reversion) + kontrakty z soft-delete#310

Open
mpasternak wants to merge 4 commits into
devfrom
docs/historia-zmian-reversion-v2
Open

docs(historia-zmian): spec wersjonowania zmian (django-reversion) + kontrakty z soft-delete#310
mpasternak wants to merge 4 commits into
devfrom
docs/historia-zmian-reversion-v2

Conversation

@mpasternak

Copy link
Copy Markdown
Member

Utrwala ustalenia z brainstormingu: widoczna w adminie historia edycji
rekordów (kto/kiedy/co + compare + revert) przez rozszerzenie istniejącego
django-reversion na zdefiniowany zbiór modeli (zgłoszenia publikacji,
wydawnictwa, Wydawca, Autor, Wydzial, Jednostka; Uczelnia już ma).

Cel: rozliczalność edycji ludzkich („kto usunął/zmienił to i to"), nie
total-audyt bazy. Odrzucono pghistory (total-audyt DB) i simple-history
(duplikacja tabel).

Kluczowe — 3 kontrakty integracyjne z trwającym projektem soft-delete (sekcja 6):

  1. soft-delete i restore muszą tworzyć rewizję reversion (set_user +
    set_comment), inaczej „kto usunął" nie pojawi się w zakładce Historia;
  2. wspólny punkt wstrzyknięcia request.user dla reversion i SoftDeleteLog;
  3. MRO CompareVersionAdmin + mixin soft-delete, get_queryset → global_objects
    (usunięty rekord otwieralny), ukrycie reversion „recover deleted".

Komplementarny do SoftDeleteLog (loguje zdarzenia delete/restore) — reversion
trzyma pełną oś edycji pól. Zawiera commit z poprawkami po self-review
(zweryfikowane w kodzie pakietów: CompareVersionAdmin wymagany do diffa,
recover ukrywany z powodu hard-delete, warunek delete() musi wołać save()).

Implementacja odłożona do po wdrożeniu soft-delete; referencje do kodu
wymagają aktualizacji po jego wejściu — ustalenia zostają.

Closes #307


⚠️ Uwaga o diffie (PR stackowany). Gałąź odbita jest od lineage soft-delete
(50d5a4), żeby odwołania w spec-u do 2026-06-04-soft-delete-publikacje-i-autorzy-design.md
się rozwiązywały. Dopóki PR #304 (soft-delete spec) nie wejdzie do dev, ten
diff pokazuje też 2 commity soft-delete (002ee, 50d5a4) jako bazę. Po
mergu #304 znikną z diffa, zostanie sam plik historii zmian. Do scalenia
po #304.

🤖 Generated with Claude Code

mpasternak and others added 4 commits June 3, 2026 22:23
…ji (ODŁOŻONE)

Analiza wprowadzenia soft-delete dla Wydawnictwo_Ciagle/Zwarte,
Praca_Doktorska, Praca_Habilitacyjna, Patent. Status: świadomie
odłożone — to spec/rozpoznanie, nie zlecenie implementacji.

Kluczowe ustalenia:
- choke-point w triggerze bpp_refresh_cache(): "deleted_at IS NOT NULL"
  traktowany jak DELETE → wszystko czytające przez Rekord/Cache_* czyści
  się jednym ruchem,
- django-soft-delete już w repo (pyproject.toml), precedens w
  zglos_publikacje; domyślny manager ukrywa usunięte → kat. A czysta
  za darmo, kat. B (import/dedup/PBN) musi przejść na global_objects,
- kaskada/auto-undelete pakietu zweryfikowana w kodzie: strict=True
  wymaga by dzieci były SoftDeleteModel → rekomendacja Projekt A
  (override delete(), dzieci nietknięte, cache/trigger robi resztę),
- slug unique → warunkowy UniqueConstraint(deleted_at__isnull=True),
- szacunek ~2-3 tygodnie; otwarte decyzje spisane.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Zatwierdzony design (brainstorming 2026-06-04) rozszerzający feasibility-spec
o: soft-delete autora (PROTECT z pracami / soft-delete husku bez prac),
wycofanie oświadczeń z PBN przez rozszerzenie pbn_export_queue (operacja
WYCOFANIE, async+retry), dedykowany SoftDeleteLog zasilany sygnałami pakietu,
oraz admin superuser-only (kosz/filtr/przywróć/usuń-trwale).

Kluczowe decyzje:
- asymetria: pełny SoftDeleteModel dla 5 publikacji (Projekt A, trigger jako
  choke-point), ale autor soft-delete TYLKO bez prac → through-modele/doktorat
  /habilitacja NIE stają się soft-delete (mały blast radius),
- flip FK autor CASCADE→PROTECT + guard w soft delete() (PROTECT nie łapie
  UPDATE-owego soft-delete),
- synergia z deduplikator_autorow: husk po merge staje się odwracalny,
- PBN: wycofanie oświadczeń instytucji (delete_all_publication_statements),
  obiektu publikacji nie kasujemy; restore → re-WYSYLKA,
- retencja: brak auto-czyszczenia, tylko ręczny hard-delete.

Stary 2026-06-03-soft-delete-publikacje.md oznaczony jako ZASTĄPIONY.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…ontrakty integracyjne z soft-delete

Utrwala ustalenia z brainstormingu: trzymamy widoczną w adminie historię
edycji rekordów (kto/kiedy/co + compare + revert) przez rozszerzenie
istniejącego django-reversion na zdefiniowany zbiór modeli (zgłoszenia
publikacji, wydawnictwa, Wydawca, Autor, Wydzial, Jednostka; Uczelnia już ma).

Cel: rozliczalność edycji ludzkich ("kto usunął/zmienił to i to"), NIE
total-audyt bazy. Odrzucono pghistory (total-audyt DB) i simple-history
(duplikacja tabel, dublowanie paradygmatu).

Kluczowe: 3 kontrakty integracyjne z trwającym projektem soft-delete —
(1) soft-delete i restore muszą tworzyć rewizję reversion (set_user +
set_comment), inaczej "kto usunął" nie pojawi się w zakładce Historia;
(2) wspólny punkt wstrzyknięcia request.user dla reversion i SoftDeleteLog;
(3) MRO VersionAdmin + mixin soft-delete, get_queryset->global_objects
(usunięty rekord otwieralny), ukrycie reversion "recover deleted".

Komplementarny do SoftDeleteLog: ten loguje zdarzenia delete/restore,
reversion trzyma pełną oś edycji pól. Implementacja odłożona do po
soft-delete; referencje do kodu wymagają aktualizacji po jego wdrożeniu,
ustalenia zostają.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…cover→hard-delete, warunki)

Korekty po self-review zweryfikowanym w kodzie pakietów:

- compare: reversion_compare zainstalowany, ale ŻADEN admin nie używa
  CompareVersionAdmin (grep 0); Uczelnia ma goły VersionAdmin (oś+revert,
  bez diffa pól). Rekomendacja zmieniona na CompareVersionAdmin jako baza
  dla nowych adminów + nota o podniesieniu Uczelni.
- szablon: ostylowany object_history.html nie ma selektora wersji do
  compare — wymaga rozszerzenia o radio-inputy (banał, ale konieczny).
- recover: soft-deletowane obiekty NIE pojawiają się w reversion recover
  (wiersz istnieje; get_deleted patrzy na nieistniejące). Uzasadnienie
  ukrycia poprawione: realny konflikt to hard_delete (wskrzeszenie poza
  przepływem PBN/SoftDeleteLog/slug).
- snippet 6.1: użycie wbudowanego self.create_revision(request) (sam robi
  set_user) + twardy warunek: nadpisany delete()/restore() musi wołać
  save() (pakiet robi save(update_fields), post_save→reversion); bulk
  update() po cichu wyłączyłby historię usunięć.
- inline follow: jest automatyczny dla zadeklarowanych inline'ów
  (admin.py:145-154) — uwaga złagodzona; caveat dot. relacji spoza inline.
- zgłoszenia: tworzone przez userów (front-end), edytowane w adminie →
  reversion pokrywa edycję; nota niskiej wagi o starcie historii.
- dopisana zaleta: włączenie reversion nie wymaga migracji (kontra
  simple-history).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Historia zmian rekordów (django-reversion) — rozliczalność edycji + integracja z soft-delete

1 participant