feat(import_polon): migracja z long_running na django-liveops#617
Open
mpasternak wants to merge 4 commits into
Open
feat(import_polon): migracja z long_running na django-liveops#617mpasternak wants to merge 4 commits into
mpasternak wants to merge 4 commits into
Conversation
…ress Rdzeń analyze_file_import_polon / analyze_file_import_absencji dostaje wymagany parametr ``p`` (liveops.Progress): pętle przechodzą na ``p.track(...)`` (throttlowany pasek + check_cancelled per wiersz), a błędy wczytania pliku raportują ``p.log(...)`` zamiast ręcznych ``send_progress`` / ``send_notification``. Model wciąż jest legacy ``Operation``, więc ``perform()`` buduje LOKALNY ``_LegacyProgressBridge`` forwardujący emisje do starego API ``ASGINotificationMixin`` (pasek postępu na dotychczasowej stronie details działa dalej między Fazą 1 a 2). ``check_cancelled`` jest no-op — legacy Operation nie ma pola ``cancel_requested``, więc realny track w celery nie rzuci ValueError. Call-site'y testów rdzenia przechodzą na ``MockProgress(model)``. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Oba importery (POLON + absencji) przechodzą z long_running
(Operation + ASGINotificationMixin) na liveops.LiveOperation: kanały
liveop.<pk>, podpisany subscription_token, snapshot-on-connect,
throttlowany progress, runner celery. Cutover jest atomowy — model,
widoki, URL-e, szablony oraz domknięcie dry-run→„zapisz do bazy" muszą
przejść w jednym zielonym commicie (wspólna klasa bazowa, jedna migracja,
wspólny ZapiszDoBazyMixin, jeden urls.py).
Model (0017_liveops): AlterModelOptions ordering=-created_on, usunięcie
last_updated_on, +10 pól liveops, owner related_name="+". run(self, p)
woła rdzeń z Progress i finalizuje p.result({"total": ...}); on_restart()
kasuje wiersze-dzieci; reset_liveops_state() zeruje stan przed re-enqueue.
Widoki: PokazImporty/PokazImportyAbsencji = owner-scoped ListView
(zachowane zawężenie multi-hosted + per-uczelnia trim dla POLON);
UtworzImport* = CreateLiveOperationView (POLON przypina uczelnię z
requestu); *ResultsView = ListView z paginate_by=25 + object=parent_object
(inaczej NoReverseMatch / cicha utrata paginacji), zachowany filter_form +
raport niezmatchowanych; ZapiszDoBazyMixin owner-scope bez long_running,
POST: flip flagi + on_restart + reset + transaction.on_commit(enqueue),
redirect na get_absolute_url; restart gejtowany grupą
(_PkOwnerRestartMixin(GroupRequiredMixin, RestartView), precedens #508 F4).
Szablony: nowe host/result (import_pliku_polon[_result].html + absencji) z
OBOWIĄZKOWYM wrapperem CSRF (CSRF_COOKIE_HTTPONLY=True); liczniki z
operation.get_details_set() (stare importy mają result_context=NULL); nowy
importplikuabsencji_list.html (bugfix index-absencji); linki na
get_absolute_url; usunięte *_detail.html + include operation_details.
Testy: przepisany test_zapisz_do_bazy.py (11) na liveops enqueue; nowe
test_liveops.py (run finalizuje, strona live + wrapper CSRF, restart
gejtowany grupą — asercja po efekcie ubocznym, 302→login nie 403).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…ch liveops Review PR #617: dodane testy potwierdzające, że anonim na utworz-import (CreateLiveOperationView) i restart (_PkOwnerRestartMixin/RestartView) dostaje 302→login, nie 500. braces GroupRequiredMixin.dispatch jest najbardziej z lewej w MRO i short-circuituje anona przed liveops BaseLiveOperationMixin (który woła bez-argumentowe handle_no_permission) — POLON nie ma kolizji, którą raport_slotow rozwiązuje compat-mixinem. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Co się zmienia
Migracja obu importerów w
import_polon— importu z POLON(
ImportPlikuPolon) oraz importu absencji (ImportPlikuAbsencji) — zestarego mechanizmu
long_running(Operation+ASGINotificationMixin,kanały
?extraChannels=[pk]) nadjango-liveops0.4: kanałyliveop.<pk>,podpisany
subscription_token, snapshot-on-connect, throttlowany progress,runner celery. Wzorem był scalony wcześniej
import_pracownikow.Zachowane (bez regresji)
importu, raport niezmatchowanych autorów, guard mutacji autora obcej
uczelni oraz zawężenie listy importów do uczelni z requestu
(
test_multi_uczelnia_scoping.pybez zmian merytorycznych).ponowne uruchomienie z zapisem (
ZapiszDoBazyMixin, owner-scope bezlong_running; enqueue odroczony przeztransaction.on_commit).Bugfix
Strona „import absencji" (
index-absencji) pokazywała dotąd listęimportów POLON zamiast absencji — teraz ma własny widok
PokazImportyAbsencji+ szablonimportplikuabsencji_list.html.Fazy
analyze_file_import_polon/absencji) przyjmujeliveops
Progress(p.track+p.log); model wciąż legacy, więcperform()forwarduje przez lokalny_LegacyProgressBridge(
check_cancelledno-op — legacyOperationnie macancel_requested).0017_liveops) + widoki +URL-e + szablony (host/result z obowiązkowym wrapperem CSRF, bo
CSRF_COOKIE_HTTPONLY=True) + przepisanytest_zapisz_do_bazy.py(11testów). ResultsView z
paginate_by=25+object=parent_object. Restartgejtowany grupą „wprowadzanie danych" (
_PkOwnerRestartMixin, precedensfeat(import_pracownikow): Faza 0 — migracja na django-liveops + dry-run #508 F4).
(polish live-UI:
stages) pominięta jako opcjonalna.Testy
PYTEST_TESTCONTAINERS_REUSE=1 uv run pytest src/import_polon/— 59passed (w tym multi-uczelnia, zapisz-do-bazy ×11, nowe
test_liveops.py:finalizacja
run(), strona live + wrapper CSRF, restart gejtowany grupą zasercją po efekcie ubocznym — 302→login, nie 403).
DJANGO_BPP_SKIP_DOTENV=1 uv run python src/manage.py makemigrations --check --dry-run— czysto dla aplikacji BPP (import_polonbez dryfu; listująsię tylko pakiety third-party: favicon/flexible_reports/siteblog).
Baseline
Nie odświeżany w tym branchu (świadomie) — wymaga
make baseline-updateprzy merge (nowa migracja
0017_liveopszmienia schemat obu tabel).🤖 Generated with Claude Code