Skip to content

feat: migracja import_list_ministerialnych z long_running na django-liveops#439

Open
mpasternak wants to merge 5 commits into
devfrom
feat/liveops-import-list-ministerialnych
Open

feat: migracja import_list_ministerialnych z long_running na django-liveops#439
mpasternak wants to merge 5 commits into
devfrom
feat/liveops-import-list-ministerialnych

Conversation

@mpasternak

@mpasternak mpasternak commented Jul 3, 2026

Copy link
Copy Markdown
Member

Cel

PoC migracji najbardziej rozbudowanego importu (import_list_ministerialnych — filtrowana tabela wyników, statystyki, detal wiersza, tracking duplikatów) z wewnętrznego src/long_running na pakiet django-liveops (live UI po WebSocket + HTMX).

Po merge z dev (który dostał własną integrację liveops przez deduplikator_zrodel) cała infrastruktura — liveops w INSTALLED_APPS, LiveOperationConsumer w asgi.py, centralny mount live/ w root urls.py — jest już na dev; ten PR dokłada do niej tylko konwersję samej aplikacji.

Zmiany

Infra (delta względem dev)

  • LIVEOPS["REQUIRED_GROUP"] = "wprowadzanie danych" — bramkuje wszystkie operacje live; od liveops 0.2 superuserzy są zwolnieni z bramki, a to ta sama grupa, którą gate'ują widoki deduplikator_zrodel → zero regresji
  • komentarz przy django-liveops[celery] w pyproject.toml

Konwersja aplikacji (bez warstwy pośredniej)

Routing live/cancel/restart jest generyczny (op_type = <app_label>.<model_name>) i mieszka w samym pakiecie (liveops.urls) — wcześniejsza koncepcja cienkiej warstwy bpp_liveops okazała się zbędna i została usunięta z PR-a.

  • model: Operation+ASGINotificationMixinLiveOperation; perform()run(self, p)
  • core.py: send_progressp.track() (dorzuca anulowanie per wiersz); send_notificationp.log(); błąd finalizowany wyjątkiem (łapie go runner liveops)
  • widoki: create → redirect na reverse("liveops:live", op_type=..., pk=...); router/details/restart usunięte; tabela wyników jako owner-scoped ListView
  • szablony: host-page + fragment wyniku; usunięte include long_running
  • migracja 0009 (usuwa last_updated_on, dodaje pola liveops)
  • lint: E402 w urls.py, B904 w core.py naprawione; odziedziczona złożoność C901 (detect_duplicates, analyze_excel_file_...) pod # noqa — jak w ewaluacja_optymalizacja

Weryfikacja

  • 15 passed (src/import_list_ministerialnych/), po merge z dev także deduplikator_zrodel + long_running zielone lokalnie (100 passed; 1 znany, środowiskowy fail test_perform_generic_long_running_task_no_tries_max_tries występuje identycznie na czystym origin/dev)
  • manage.py check + makemigrations --check: czysto
  • uv lock --check: zgodny

Świadomie odłożone

  • Baseline (make baseline-update) — zgodnie z regułą repo robimy raz przy scalaniu, nie w feature-branchu. Migracja 0009 jeszcze nie w baseline.
  • E2E celery + WebSocket — testy pokrywają run() i render host-page, ale nie żywy worker+Daphne+xlsx (zalecany ręczny smoke przez run-site)
  • Pozostałe ~8 apek nadal na long_running — wzorzec konwersji gotowy do powielenia

🤖 Generated with Claude Code

mpasternak and others added 5 commits July 3, 2026 17:02
…liveops

Konwersja najbardziej rozbudowanego importu (filtrowana tabela wyników,
statystyki, detal wiersza, tracking duplikatów) z wewnętrznego
`src/long_running` na pakiet `django-liveops` (live UI: WebSocket + HTMX).

Infra:
- django-liveops>=0.1,<0.2 (PyPI) w zależnościach
- INSTALLED_APPS: liveops + bpp_liveops; blok LIVEOPS (RUNNER=celery)
- asgi: LiveOperationConsumer (drop-in nadzbiór NotificationsConsumer)
- root urls: centralny namespace ^live/ (liveops:live/cancel/restart)

Cienka warstwa bpp_liveops:
- BppLiveOperation (abstract): reset_children() + readable_exception()
- centralne generyczne widoki rozwiązujące model po UUID
- gating grup przez braces (superuser-exempt, parytet z long_running)

Konwersja aplikacji:
- model: Operation+ASGINotificationMixin -> BppLiveOperation;
  perform() -> run(self, p); on_reset -> reset_children
- core: send_progress -> p.track (dorzuca anulowanie); send_notification -> p.log
- widoki: create -> CreateLiveOperationView; router/details/restart usunięte;
  tabela wyników jako owner-scoped ListView
- szablony: host-page + fragment wyniku; usunięte include long_running
- migracja 0009 (usuwa last_updated_on, dodaje pola liveops)

Testy: 13 zastanych zaktualizowanych (FakeProgress) + 2 nowe integracyjne
(run() -> finalizacja z result_context; render centralnej strony live).
15 passed. Baseline do odświeżenia przy scalaniu.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
… usuń bpp_liveops

django-liveops 0.2.0 przeniósł generyczny routing live-operacji do samego
pakietu (op_type = <app_label>.<model_name> w URL-u, rozwiązanie modelu
jednym apps.get_model — bez skanu rejestru). Dzięki temu cała warstwa
pośrednia bpp_liveops jest zbędna i znika.

- pyproject: django-liveops >=0.2,<0.3 (z PyPI)
- model: dziedziczy po liveops.LiveOperation wprost; reset_children -> hook
  on_restart (wołany przez RestartView pakietu)
- root urls: include("liveops.urls") zamiast bpp_liveops.urls (koniec skanu)
- settings: usunięto bpp_liveops z INSTALLED_APPS; REQUIRED_GROUP przywrócony
  (od 0.2 liveops zwalnia superuserów z bramki — brak regresji)
- usunięto src/bpp_liveops/ w całości (-159 linii)

get_absolute_url() -> /live/import_list_ministerialnych.importlistministerialnych/<uuid>/
Testy: 15 passed na czystym 0.2.0 z PyPI. manage.py check czysto.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…ress

django-liveops 0.3.0 brings the CSRF fix (cancel/restart on the live page),
htmx cancel/restart, get_success_url, and MockProgress. Bump the pin and:

- swap the hand-rolled FakeProgress in tests for liveops.testing.MockProgress
  (records calls + finalizes the operation) — the finalization test drops
  TextProgress/io for MockProgress too;
- simplify the host page: the "see full results" link now lives only in the
  result panel (shown on completion), not persistently above it.

Tests: 15 passed on 0.3.0. manage.py check clean.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Konflikty rozwiązane:
- pyproject.toml: django-liveops[celery]>=0.3,<0.4 (extra [celery] z dev,
  komentarz z brancha)
- asgi.py: wersja z dev — pbn_import.routing usunięty na dev (#360),
  liveops.routing importowany raz (naprawia też lint import-sort)
- settings/base.py: scalone komentarze LIVEOPS; REQUIRED_GROUP zostaje
  (ta sama grupa co gating widoków deduplikator_zrodel, superuserzy
  zwolnieni od liveops 0.2); dedup podwójnego "liveops" w INSTALLED_APPS
- urls.py: dedup podwójnego mountu liveops.urls pod live/
- uv.lock: wersja z dev (uv lock --check przechodzi)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- urls.py: import views przed app_name (E402)
- core.py: raise ValueError(...) from e (B904); noqa C901 dla
  odziedziczonej złożoności detect_duplicates (12) i
  analyze_excel_file_import_list_ministerialnych (26) — refactor poza
  zakresem tego PR, konwencja jak w ewaluacja_optymalizacja

Co-Authored-By: Claude Fable 5 <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.

1 participant