Skip to content

feat(import_list_if): migracja z long_running na django-liveops#616

Open
mpasternak wants to merge 4 commits into
devfrom
feat/import-list-if-liveops
Open

feat(import_list_if): migracja z long_running na django-liveops#616
mpasternak wants to merge 4 commits into
devfrom
feat/import-list-if-liveops

Conversation

@mpasternak

Copy link
Copy Markdown
Member

Co się zmienia

Migracja aplikacji import_list_if z legacy stacku long_running na
django-liveops 0.4 — postęp importu na żywo przez WebSocket, spójny z
import_punktacji_zrodel / import_pracownikow. Wzorzec 1:1 na już-scalonym
import_punktacji_zrodel.

  • ImportListIf dziedziczy wprost po liveops.models.LiveOperation.
  • Retire abstrakcyjnego import_common.models.ImportOperation — był to jego
    jedyny użytkownik; pola/logika (plik_xls, get_xls_import_file,
    get_validation_form_class, ignore_bad_rows) wchłonięte do ImportListIf.
    ImportRowMixin zostaje (używa go import_pracownikow). Sama aplikacja
    long_running zostaje (10+ innych modułów na niej stoi).
  • perform()run(self, p): postęp/anulowanie przez obiekt Progress.
    Ciało owinięte w transaction.atomic() dla parytetu z legacy task_perform
    (all-or-nothing) — OperationCancelled/XLSParseError cofa zapisane wiersze;
    p.result(...) poza blokiem (defer push przez transaction.on_commit).
  • on_reset()on_restart() (hook RestartView).
  • Widoki na liveops: owner-scoped ListView (lista), CreateLiveOperationView
    (nowy import), owner-scoped ResultsView (paginate_by=25,
    object=parent_object). Bramka grupy przez braces GroupRequiredMixin
    (GR_WPROWADZANIE_DANYCH) — liveops nie ma REQUIRED_GROUP w BPP.
  • URL-e: zostają index/new/importlistif-results; usunięte
    router/detale/regen (strona live → centralny liveops:live, restart →
    centralny liveops:restart).
  • Szablony: nowy host import_list_if.html (wrapper hx-headers z CSRF wokół
    {% live_operation object %}), nowy import_list_if_result.html (panel
    wyniku). Naprawiony importlistif_list.html (link → get_absolute_url,
    breadcrumb import_list_if:index zamiast błędnego import_pracownikow:index).
    Oczyszczony importlistifrow_list.html (bez long_running/operation_details),
    usunięty martwy {% load render_table %} i skasowany importlistif_detail.html.
  • Nowa migracja delta 0005_liveops.py (pola liveops, usunięcie
    last_updated_on, owner related_name="+", ordering=-created_on).

Fazy

  1. Model + migracja + testy modelu (MockProgress).
  2. Widoki + URL-e + szablony + testy widoków (domyka cutover).
  3. Sprzątanie + newsfragment.

Testy (lokalnie, testcontainers PG/Redis)

  • src/import_list_if/10 passed (model: run/finalize/anulowanie z
    rollbackiem/on_restart; widoki: create→redirect liveops:live+4 wiersze,
    bramka grupy 302 redirect_to_login bez side-effectu, owner-scoping→Http404).
  • src/import_common/ + src/import_punktacji_zrodel/406 passed
    (bezpieczeństwo retire ImportOperation).
  • src/import_pracownikow/658 passed (drugi konsument ImportRowMixin).
  • manage.py check — bez uwag; pre-commit na zmienionych plikach — zielono.
  • makemigrations --check --dry-run import_list_if import_pracownikow import_punktacji_zrodelNo changes detected (brak driftu).

Baseline

⚠️ Baseline: wymaga make baseline-update przy merge (nowa migracja
schematu 0005_liveops). Świadomie NIE odświeżany w tym branchu (reguła:
baseline raz, przy scalaniu do dev — równoległe branche = nierozwiązywalny
konflikt na jednym pliku).

🤖 Generated with Claude Code

mpasternak and others added 4 commits July 16, 2026 20:58
…racja)

Faza 1 migracji import_list_if z legacy long_running na django-liveops 0.4:

- ImportListIf dziedziczy wprost po liveops.models.LiveOperation; wchłania
  z retirowanego import_common.ImportOperation pola/logikę (plik_xls,
  get_xls_import_file, get_validation_form_class, ignore_bad_rows).
- perform() przepisane na run(self, p): postęp/anulowanie przez obiekt
  Progress; ciało owinięte w transaction.atomic() dla parytetu z legacy
  task_perform (all-or-nothing) — OperationCancelled cofa zapisane wiersze.
  p.result(...) poza blokiem (defer push przez transaction.on_commit).
- on_reset() -> on_restart() (hook liveops RestartView).
- Skasowany abstrakcyjny import_common.models.ImportOperation (jedyny
  użytkownik); ImportRowMixin zostaje (używa go import_pracownikow).
- Nowa migracja delta 0005_liveops (pola liveops, usunięcie last_updated_on,
  owner related_name="+", ordering -created_on) — mirror import_pracownikow
  0010, bez stan/RunPython.
- Testy modelu przepisane na liveops.testing.MockProgress; nowy test
  anulowania (raises OperationCancelled + 0 wierszy) i finalizacji operacji.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Faza 2 migracji import_list_if — domyka cutover (dopiero tu apka działa):

- views.py przepisane na liveops: ListaImportowView (owner-scoped ListView),
  NowyImportView(CreateLiveOperationView), ImportListIfResultsView
  (owner-scoped ListView z paginate_by=25 i object=parent_object). Bramka
  grupy przez braces GroupRequiredMixin (GR_WPROWADZANIE_DANYCH z bpp.const,
  nie literał) — liveops nie ma REQUIRED_GROUP w BPP.
- urls.py: zostają index/new/importlistif-results; usunięte router, detale
  i regen (restart) — strona live idzie przez centralny liveops:live,
  restart przez centralny liveops:restart.
- Szablony: nowy host import_list_if.html (hx-headers CSRF + live_operation),
  nowy import_list_if_result.html (panel wyniku + link do wyników). Naprawiony
  importlistif_list.html (link → get_absolute_url, breadcrumb import_list_if
  zamiast import_pracownikow). Oczyszczony importlistifrow_list.html (bez
  include long_running/operation_details). Usunięty martwy load render_table
  i skasowany importlistif_detail.html (zastąpiony host template).
- get_details_set() sortuje po id (kolejność w pliku) → deterministyczna
  paginacja tabeli wyników.
- test_views.py: create POST → redirect na liveops:live + 4 wiersze (eager),
  bramka grupy (302 redirect_to_login + brak side-effectu, NIE 403),
  owner-scoping tabeli wyników (cudzy import → Http404).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Faza 3: sprzątanie + newsfragment. Potwierdzone: poza historycznymi
komentarzami i nietykalną migracją 0001, import_list_if/import_common nie
odwołują się już do long_running/ImportOperation; sama aplikacja
long_running zostaje (używa jej 10+ innych modułów).

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

Review PR #616: ImportListIfResultsView.parent_object używał .get(pk=...),
co dla nieistniejącego pk dawało 500 zamiast 404 — parytet z
get_object_or_404 we wzorcu import_pracownikow. Dodany test regresji 404
oraz test anon→302 (nie 500) na gejtowanym liveops CreateView (potwierdza
brak kolizji handle_no_permission, którą ma raport_slotow). Poprawiony
mylący komentarz o transaction.on_commit w run().

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.

1 participant