feat(profil-autora): Faza 1 — konfigurowalne sekcje podstrony autora + pola profilu#385
Open
mpasternak wants to merge 43 commits into
Open
feat(profil-autora): Faza 1 — konfigurowalne sekcje podstrony autora + pola profilu#385mpasternak wants to merge 43 commits into
mpasternak wants to merge 43 commits into
Conversation
… autora Projekt z sesji brainstormingu: konfigurowalne sekcje podstrony autora (kolejnosc/widocznosc/limit), nowe pola Autor (zdjecie WebP 400x400, biogram + biogram_format md/html), model WybranaPublikacjaAutora, rejestr sekcji w kodzie + uklad_profilu JSON, render z auto-ukrywaniem pustych, linki do raportu wg widoczny_dla, wspolautorzy z AuthorConnection + CTA do browsera 2D/3D. Dostawa fazowa: Faza 1 (model+render+admin), Faza 2 (self-service edytor + RIS). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…rejestr sekcji Czyste jednostki (TDD, 27 testów): - bpp.util.biogram.renderuj_biogram: Markdown/HTML → bezpieczny HTML przez nowy safe_biogram_html (bogatszy zestaw tagów blokowych niż wąski globalny safe_html; usuwa treść script/style; linki dostają rel=nofollow noopener). - bpp.util.obrazy.przetworz_zdjecie_autora: EXIF→crop kwadrat→WebP 400x400. - bpp.profil_autora: katalog typów sekcji + walidacja i rozwiązywanie układu (kolejność/widoczność/limit, wymuszona wyszukiwarka, forward-compat). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…utora Autor: zdjecie (ImageField), biogram + biogram_format (md/html), uklad_profilu (JSONField) oraz cached_property biogram_html. Nowy model WybranaPublikacjaAutora (GenericFK do polimorficznej publikacji). Migracja 0444. Baseline odświeżyć przy scalaniu (make baseline-update). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
… + style - profil_autora_dane: buildery danych każdej sekcji (listy prac, statystyki, wykres lat, dyscypliny, źródła, współautorzy z AuthorConnection) + auto- ukrywanie pustych sekcji. - AutorView: render sekcji wg uklad_profilu (lub domyślnego) + linki do raportu autora (bieżący rok / 4 lata / formularz) gated DefinicjaRaportu .widoczny_dla. - browse/autor.html: stały nagłówek (z awatarem) + pętla sekcji; formularz wyszukiwania wydzielony do sekcji autor_sekcje/wyszukiwarka.html; partiale wszystkich sekcji; embed-kod bez zmian. - AutorAdmin: fieldset profilu (zdjęcie/biogram/format/układ), przetwarzanie zdjęcia w AutorForm.clean_zdjecie (≤5MB → WebP 400x400), inline wybranych publikacji. - SCSS: style sekcji (awatar, listy, tabele statystyk, wykres słupkowy, współautorzy, linki raportu). Testy: 4 integracyjne (render biogramu/wyszukiwarki, ukrywanie sekcji, linki raportu public/inactive). Cała suita test_profil + istniejące test_autor_autorzy zielone (43) na świeżym kontenerze — bez regresji. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Django-generated migracja miała linie >88 znaków; CI "Lint changed files" uruchamia ruff-format na zmienionym zakresie z --exit-non-zero-on-fix. To nowy plik migracji (nie istniejący), więc formatowanie jest dozwolone. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Import bpp.util.biogram należy do grupy first-party (po bpp.util), nie do grupy third-party po tinymce. Poprawka nie trafiła do poprzedniego commita. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Spisane decyzje z 2026-06-19: układ 2-kolumnowy (lewa=klasyka+wizytówka, prawa=kafelki analityczne), układ globalny per-Uczelnia (multi-uczelnia, get_for_request), edytor kafelkowy admin-only, autor edytuje tylko biogram+zdjęcie, klik w całą pozycję pracy, line-clamp opisów, wykres liniowy >10 lat, klik w charakter → wyszukiwarka, historia zatrudnienia, wykresy PK/IF. Dokument samowystarczalny dla wznowienia po resecie sesji. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…ablon 2-kolumnowy Rewizja 2-kolumnowa (§3.1–§3.3 handoffa): - Układ profilu jest teraz GLOBALNY per-Uczelnia (multi-uczelnia): nowe pole Uczelnia.uklad_profilu_autora (JSONField). Usunięto Autor.uklad_profilu (override per-autor zbędny). Migracja 0445 (AddField Uczelnia + RemoveField Autor; 0444 nietknięta). - rozwiaz_uklad(uczelnia), przygotuj_sekcje(autor, uczelnia, request). - Rejestr KATALOG_SEKCJI obejmuje tylko PRAWĄ kolumnę: usunięto biogram/wyszukiwarka/eksport oraz pole TypSekcji.obowiazkowa. Dodano klucze wykres_pk_lata + wykres_if_lata (buildery w §3.5). - Szablon browse/autor.html przebudowany na Foundation grid w HTML (cell large-4 lewa: zdjęcie→biogram→jednostka→[historia §3.7]→ identyfikatory→metryki→stopnie→opis→cytowania→wyszukiwarka→raport; cell large-8 prawa: pętla sekcji). Biogram i wyszukiwarka są stałe w lewej kolumnie (nie konfigurowalne). - Admin: usunięto uklad_profilu z AutorForm/fieldsetu (edytor układu na Uczelni dochodzi osobnym commitem). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- _lista_prac.html: usunięto link [szczegóły]; każda pozycja <li> niesie data-href = praca.get_absolute_url, role="link", tabindex=0; opis w kontenerze .autor-page__praca-opis (line-clamp dochodzi w SCSS). - autor.html: delegowany handler kliku/Enter nawiguje do data-href, pomijając kliknięcia w wewnętrzne <a> (DOI itp.) — bez zagnieżdżania <a> w <a>. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- Wspólny partial _wykres_lata.html: >10 punktów → liniowy SVG (polyline + punkty z tooltipami, oś Y odwrócona transformem żeby liczyć współrzędne widthratio bez odejmowania), do 10 → słupki. - _agreguj_po_latach(pary) — czysta agregacja (rok, wartosc) → suma/rok + maks + suma; pomija None. - Buildery _wykres_pk_lata (suma punkty_kbn/rok) i _wykres_if_lata (suma impact_factor/rok; None gdy suma IF == 0 → auto-hide). _wykres_lata zyskuje etykietę. DISTINCT z id neutralizuje duplikaty joinu autorzy. - Sekcje wykres_lata/wykres_pk_lata/wykres_if_lata delegują do partiala. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
… (§3.6) - statystyki_charakter.html: każdy wiersz to POST do bpp:browse_build_search z autor=<pk> + charakter_formalny=<nazwa> (+ suggested-title). Nazwa, nie pk — CharakterFormalnyQueryObject.value_from_web rozwiązuje po `nazwa` (z potomkami MPTT). - BuildSearch.post: dodano charakter_box przez CharakterFormalnyQueryObject, wpięty w oba warianty zrob_formularz (z/bez wydziałów). Zmiana addytywna — aktywna tylko gdy POST zawiera charakter_formalny. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- Autor.historia_zatrudnienia() → Autor_Jednostka filtrowane po autorze, select_related(jednostka, funkcja), order_by(-rozpoczal_prace). - _historia_zatrudnienia.html: lista „Jednostka — od–do (funkcja)"; „obecnie" gdy brak zakonczyl_prace, „?" gdy brak rozpoczal_prace. Pusta historia → sekcja się nie renderuje. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
….1 admin + SCSS) - UczelniaAdmin: nowy fieldset „Profil autora (podstrona)" z polem uklad_profilu_autora (JSON w textarea + opis). MVP edytora globalnego układu prawej kolumny. - SCSS (_autor-bem.scss): klikalna pozycja listy prac (hover/focus) + line-clamp opisu (~3 linie); wykres liniowy SVG (linia/punkty/oś X); statystyki jako link-przycisk; historia zatrudnienia; drobne style kolumn (bez nadpisywania klas grid Foundation). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…direction) CodeQL zgłosił 2 high-severity alerty dla zapisu wartości z DOM (data-href) do window.location. data-href pochodzi z get_absolute_url (zaufane), ale dla pewności i zadowolenia skanera nawigujemy WYŁĄCZNIE do ścieżek względnych w obrębie serwisu: walidacja /^\/[^/]/ odcina javascript:, //host i http(s)://. Wspólny helper nawigujDoPracy(). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…odeQL) CodeQL js/xss-through-dom flagował zapis wartości z DOM do window.location (możliwy javascript:). Eliminujemy sink całkowicie: zamiast data-href + JS używamy pustej nakładki <a> (position:absolute) pokrywającej całą pozycję; wewnętrzne linki opisu (DOI) wynosimy ponad nakładkę przez z-index. Prawdziwy, dostępny <a>, zero JS, brak zagnieżdżenia <a> w <a>. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…za 2) Zalogowany autor (user.autor) edytuje WŁASNY biogram (MD/HTML + podgląd na żywo) i zdjęcie w „Mój profil": - ProfilEdycjaView (UpdateView na request.user.autor) + AutorProfilForm (zdjecie/biogram/biogram_format), reużycie clean_zdjecie + przetworz_zdjecie_autora. WymagajAutoraMixin: anonim → login, zalogowany bez autora → przekierowanie na „Mój profil" z komunikatem. - ProfilBiogramPodgladView — AJAX podgląd przez renderuj_biogram (ten sam pipeline sanityzacji co przy zapisie; XSS wycięty). - URL-e bpp:profil-edycja, bpp:profil-biogram-podglad. Szablon z live preview (debounce, CSRF). Link „Edytuj swoją stronę" na „Mój profil". - Układ NIE jest edytowalny przez autora (globalny per-Uczelnia). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…lnosci) test_publication_fulltext_search_uses_weighted_cached_fields wołał dodaj_autora() (wymaga Typ_Odpowiedzialnosci "aut."), ale nie deklarował tej zależności — polegał na danych bazowych, które poprzedzający test transakcyjny mógł wyczyścić (flush). Dodanie testów w §3.8 zmieniło podział pytest-split na shardy i ujawniło tę latentną kruchość (shard 0). Dodajemy fixture typy_odpowiedzialnosci, która deterministycznie tworzy pełny zestaw typów (w tym "aut."). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Samowystarczalny handoff: stan brancha (CI zielone, PR #385), architektura, lekcje (CodeQL stretched-link, §3.6 charakter po nazwie, pytest-split shardy), świadomie odłożone (baseline-update + merge), oraz kandydaci na dalej (weryfikacja wizualna, edytor kafelkowy układu, eksport BibTeX/RIS, picker wyróżnionych prac). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
… kalibracja) Wykresy roczne (Publikacje/Punkty MNiSW/Impact Factor w latach) nie miały żadnego odniesienia na osi Y — wartości czytelne tylko po najechaniu. Dodaje lekką oś Y bez zależności (czysty SVG/HTML/CSS) dla obu wariantów: - liniowy (>10 lat): kolumna HTML `wykres-osY` (maks u góry, 0 u dołu) obok SVG; dwie linie siatki jako `<line>` w grupie transformowanej (y=200 maks, y=100 połowa) z `vector-effect: non-scaling-stroke` — bez dystorsji. - słupkowy (≤10 lat): etykieta maks (HTML) + górna linia siatki na poziomie najwyższego słupka. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Dwa publiczne endpointy zwracające plik do pobrania ze wszystkimi publikacjami autora: - GET /bpp/autor/<pk>/eksport.bib → BibTeX (reuse bpp.export.bibtex) - GET /bpp/autor/<pk>/eksport.ris → RIS (nowy moduł bpp.export.ris, zbudowany na wzór bibtex.py: per-typ konwertery + dispatcher) Plus dwa przyciski "Eksport publikacji" (Foundation, fi-download) w lewej kolumnie strony autora. Limit MAKS_EKSPORT=5000 chroni przed OOM przy autorach z ogromną liczbą prac; przy obcięciu BibTeX dostaje komentarz "% Wyeksportowano pierwsze N z M", RIS (format liniowy) polega na samym limicie. Testy TDD: src/bpp/tests/test_profil/test_eksport.py (6 testów, HTTP + unit + edge: pusty autor / 404). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
… dev) CI testuje branch scalony z dev. Dev dodał 0444_alter_uczelnia_wyszukiwanie (gałąź dev), profil dodał 0444_autor_biogram → 0445_remove_autor_uklad_profilu (gałąź feature) — wspólny rodzic 0443 → dwa liście grafu migracji. 0446 to pusta migracja scalająca (operations=[]) zależna od obu liści. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Zalogowany autor zarządza listą WŁASNYCH wyróżnionych publikacji na swojej podstronie: dodaje (autouzupełnianie po własnym dorobku), usuwa i zmienia kolejność. Persystencja do istniejącego modelu WybranaPublikacjaAutora (bez nowej migracji). Bezpieczeństwo egzekwowane serwerowo na każdej akcji: - WymagajAutoraMixin gatuje dostęp (anonim->login, brak user.autor->profil), - dodanie waliduje przynależność Rekordu do Rekord.objects.prace_autora(autor), - usunięcie/przesunięcie filtruje wiersze przez autor=request.user.autor, - duplikat (unique_together) to przyjazny no-op, nie 500. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
… polish) Opis bibliograficzny zawiera HTML (<b>/<i>); na liście i w podpowiedziach JS wstawia tekst przez textContent (bezpiecznie, bez DOM-XSS), więc surowe tagi były widoczne dosłownie. striptags (szablon) + strip_tags (autocomplete) dają spójny, czytelny tekst. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…(§3.2)
Zastępuje surowy textarea JSON dla Uczelnia.uklad_profilu_autora
przyjaznym, kafelkowym edytorem drag-drop w adminie uczelni:
- EdytorUkladuWidget (src/bpp/admin/widgets/uklad_profilu.py): renderuje
kafelek dla KAŻDEJ sekcji katalogu (zapisana kolejność + doklejone
brakujące z domyślem, forward-compat jak rozwiaz_uklad), z checkboxem
widoczności, selectem limitu tylko dla sekcji ma_limit i ukrytym
inputem z kanonicznym JSON-em.
- Szablon admin/widgets/uklad_profilu.html (emoji, single-line {# #}).
- JS uklad_profilu_edytor.js: jquery-ui .sortable() (z Grappelli) +
re-serializacja kafelków do ukrytego inputa na drag/checkbox/limit,
na django.jQuery, bez błędów konsoli.
- UczelniaAdminForm z clean_uklad_profilu_autora() sanityzującym przez
waliduj_uklad(); podpięty jako form na UczelniaAdmin; opis fieldsetu
zaktualizowany (drag-drop zamiast "wpisz JSON").
Serializacja zgodna ze schematem {"klucz","widoczna","limit"}
(walidowanym przez waliduj_uklad). 11 testów (TDD), wszystkie zielone.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…ji 0446) Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…ia, węższe wykresy Feedback ze strony autora: - kolumny large-4/large-8 -> large-6/large-6 (równy podział 50/50); - zdjęcie większe (220px) i klikalne -> powiększenie w modalu Reveal (fallback bez JS: <a href> otwiera pełny obraz); - historia zatrudnienia: bez sztucznej Obcej jednostki i bez wierszy bez daty rozpoczęcia (koniec z pytajnikami); filtr w modelu + przez AutorView; - wykresy roczne domyślnie ostatnie 10 lat (OKNO_LAT_WYKRESU) i węższy blok (max-width) - czytelniejsze niż pełna, rozlana historia. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Klik w charakter na stronie autora budował poprawne zapytanie, ale pole VALUE_LIST w multiseeku było puste: zapisywana goła nazwa nie równała się żadnej opcji selecta (te są etykietami MPTT z prefiksem/spacją). Dodaje CharakterFormalnyQueryObject.value_to_web mapujący nazwę na dokładną etykietę listy - pole pokazuje wartość, zapytanie bez zmian. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…rator/redaktor) Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…ct2) Wyszukiwarka „dodaj publikację" w pickerze wyróżnionych prac używała własnego widgetu (input + ręczna lista podpowiedzi), odstając wizualnie od reszty serwisu, gdzie standardem jest Select2 (django-autocomplete-light). Rekord ma złożony klucz (TupleField), więc zamiast ModelSelect2 używamy ListSelect2 (dowolne pary id/tekst) — tak jak globalna nawigacja. Endpoint zwraca teraz format DAL/Select2 (results[].text + pagination). Media (jQuery+select2) ładuje globalnie pasek nawigacji, więc nie dołączamy ich ponownie. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…onie autora Drobny feedback wizualny: - modal powiększenia zdjęcia: klik otwiera TYLKO modal (preventDefault na linku), bez nawigacji do pełnego obrazu w nowym oknie; samo zdjęcie bez białego marginesu/tła Foundation Reveal, zaokrąglone rogi (selektor dwuklasowy .reveal.<modal> bije bazowe .reveal niezależnie od kolejności importów); - statystyki wg charakteru: linki wyglądają jak zwykłe linki serwisu (kolor motywu $anchor-color, podkreślenie na hover, bez „kwadratowej ramki" / outline / box-shadow); - wyszukiwarka „Opracowane w latach": checkbox i rok ZAWSZE w jednej linii (flex + nowrap), 3 lata w wierszu zamiast 6 (large-4) — czytelniej w węższej (50/50) lewej kolumnie. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Link „Raport szczegółowy…" ze strony autora prowadził do pustego formularza — pole wyboru obiektu (Select2) nie miało wybranego autora. Teraz link przekazuje ?obiekt=<pk>, a RaportFormView.get_initial czyta ten parametr i ustawia initial, dzięki czemu DAL renderuje wybraną opcję (nazwisko autora). Działa też dla poziomu jednostki/wydziału (ten sam mechanizm). Zły/nieistniejący pk nie wywala formularza. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
) Eksport publikacji autora budowany dotychczas synchronicznie w requeście (N+1 przy materializacji [r.original ...]) przeniesiony do zadania Celery ze stroną postępu (HTMX) i pobraniem-gdy-gotowe. - Model AutorEksportTask (UUID pk, public) w src/bpp/models/eksport_autora.py - @shared_task generuj_eksport_autora + cleanup usun_stare_eksporty_autora w src/bpp/tasks.py; parytet bajt-w-bajt z widokiem synchronicznym - Widoki Start/Status/Download (publiczne, anonimowe; autoryzacja przez UUID + status), URL-e bpp:autor_eksport_{start,status,pobierz} - Szablony task_status.html + _progress.html (HTMX poll co 2s, Foundation, auto-download); przyciski na stronie autora przepięte na flow async - Stare synchroniczne URL-e/widoki zachowane (back-compat) - Beat-schedule cleanup co 24h; migracja 0447 Mitigacja nadużyć anonimowych: dedupe (reuse zadania autor+format w oknie 5 min) + twardy limit MAKS_EKSPORT=5000. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…isie Wyszukiwarka „dodaj wyróżnioną pracę" filtrowała tylko po tytule. Teraz pyta po pełnym opisie bibliograficznym (opis_bibliograficzny_cache), więc znajduje własne prace także po nazwisku WSPÓŁAUTORA, źródle czy roku — jak globalna wyszukiwarka. Każde słowo musi wystąpić (AND), więc „Nowak 2020" zawęża sensownie. Nadal wyłącznie w obrębie własnych prac autora (bezpieczeństwo). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Zdjęcie + biogram w jednej wizytówce; zdjęcie pływa w lewo, biogram opływa je z prawej i od dołu (overflow:hidden domyka float). Wcześniej zdjęcie było osobnym blokiem i zostawiało dużo pustego miejsca po prawej w szerszej (50/50) lewej kolumnie. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Każdy dawniej-sztywny blok lewej kolumny podstrony autora dostaje własny
partial w browse/autor_sekcje/ (zdjecie, biogram, jednostka, historia,
dyscypliny_naukowe, identyfikatory, metryki, stopnie, poprzednie_nazwiska,
opis, cytowania, raport, eksport). Markup przeniesiony 1:1 z autor.html
(zachowane bramki {% if %} i zamykające HR). historia_zatrudnienia.html
reużywa istniejący _historia_zatrudnienia.html.
Pliki na razie nieużywane (czysto addytywny krok) — wpięcie w układ
2-kolumnowy w kolejnym commicie. Bez zmiany zachowania, suita zielona.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Każdy element podstrony autora (lewa i prawa kolumna) jest teraz pozycją
rejestru otagowaną kolumną (lewa/prawa) z kolejnością, widocznością i
limitem — edytowalną per-Uczelnia. Domyślny układ odwzorowuje dzisiejszą
stronę (te same bloki lewej, te same sekcje prawej, 50/50).
Rejestr (profil_autora.py):
- TypSekcji.kolumna (+ template_only); schemat pozycji
{klucz, kolumna, widoczna, limit}.
- KATALOG_SEKCJI obejmuje wszystkie bloki lewej kolumny + dotychczasowe
prawe. Blok tożsamości „Dyscypliny naukowe" jako dyscypliny_naukowe
(różny od statystycznej sekcji dyscypliny).
- waliduj_uklad uzupełnia brakującą kolumnę z katalogu (back-compat dla
starych zapisów bez kolumny → prawa).
- rozwiaz_uklad zwraca dict {lewa, prawa}; sekcje spoza configu doklejane
w swojej domyślnej kolumnie.
Dane (profil_autora_dane.py): przygotuj_sekcje zwraca obie kolumny;
sekcje template-only zawsze dołączane (partial sam się bramkuje),
data-driven pomijane gdy builder zwróci None.
Szablon (autor.html): obie kolumny renderowane z configu; szerokość lewej
z Uczelnia.szerokosc_lewej_kolumny (prawa = 12 - lewa). Float zdjęcia
domyka kolumna (flow-root) + clear na sekcjach (SCSS) — biogram opływa
zdjęcie jak dziś.
Model: Uczelnia.szerokosc_lewej_kolumny (4/6/8, default 6), migracja 0448.
Admin: dwustrefowy edytor kafelkowy (lewa ⇄ prawa, jquery-ui sortable
connectWith), serializacja z kolumną; pole szerokości w fieldset
„Profil autora (podstrona)".
Testy: test_uklad / test_edytor_ukladu / test_widok zaktualizowane do
nowego kontraktu (dict, kolumna, dwie strefy, szerokość, przeniesienie
biogramu do prawej); nowy test_przygotuj_sekcje. Cała suita test_profil
zielona (126 passed).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
# Conflicts: # docs/redaktor/autorzy.md # src/bpp/admin/uczelnia.py # src/bpp/models/autor.py # src/bpp/templates/browse/autor.html # src/bpp/tests/test_fulltext_search.py # src/bpp/views/browse.py # src/nowe_raporty/tests/test_generyczne_widoki.py
Po scaleniu z dev renderowanie podstrony autora BEZ skonfigurowanej uczelni (pusta baza / testy bez fixture'u) wywalało 500: base.html rozwiązuje `uczelnia.skrot` twardo w breadcrumbie, a context-processor wstrzykuje w takim przypadku sentinel `NiezdefiniowanaUczelnia` (ma `.skrot="NdU"`). AutorView jednak przekazywał jawnie `uczelnia=None`, przesłaniając sentinel None-em. Teraz klucz `uczelnia` trafia do kontekstu tylko gdy uczelnia istnieje; przy None sentinel z context-processora zostaje nienaruszony. Logika Python-owa (szer_lewej, link_do_pbn, przygotuj_sekcje, historia_zatrudnienia) dalej dostaje realne None i jest na nie odporna (getattr / metody tolerują None). Naprawia 8 testów test_profil/test_widok.py, które renderują podstronę bez fixture'u `uczelnia`; jednocześnie usuwa latentny 500 w produkcji. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
mpasternak
added a commit
that referenced
this pull request
Jul 7, 2026
Rozdział: dziedziczenie wydawcy po wydawnictwie nadrzędnym + podświetlenie wymaganego pola (Freshdesk #385)
Sekcja na podstronie autora pobierająca na żywo (client-side) dane z RAD-on scientist/search dla autorów z ORCID: stopnie/tytuły/wykształcenie/ zatrudnienie/dyscypliny. Dopasowanie po nazwisku + weryfikacja po ORCID (scientist zwraca personalData.orcid). CORS otwarty. Ludzie Nauki i projekty/publikacje świadomie poza zakresem (CORS zamknięty / brak filtra po osobie). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…POL-on Odkryte usługi POL-on filtrowalne po osobie (wszystkie CORS otwarty, client-side): polon/projects (po kierowniku, weryfikacja projectManagers[].ORCID), polon/products (patenty, po wynalazcy, inventors[].persons[].relatedOrcid), polon/artisticAchievements (po autorze, authors[].orcid, + nagrody). Publikacje świadomie pominięte (są w bazie BPP). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Nowa sekcja template-only 'Osiągnięcia (RAD-on)' na podstronie autora, widoczna dla autorów z ORCID. Dane pobierane na żywo w przeglądarce z RAD-on OpenData przez @iplweb/radon-opendata (bundlowany esbuildem), dopasowane po ORCID: stopnie/tytuły, projekty (z kwotami), patenty, osiągnięcia artystyczne. Publikacje pominięte (są w bazie BPP). - profil_autora: KLUCZ_RADON + wpis w KATALOG_SEKCJI (lewa kolumna) - partial radon_osiagniecia.html: kontener [data-radon-osiagniecia], bramka po autor.orcid, podpis 'informacje pobrane z RAD-on' - radon-profil.js: render przez textContent (anty-XSS), degradacja per-kontener bez wyjątku; wpięty w bundle-entry.js - testy: 3 pytest (katalog + render kontenera) + 5 vitest (render/wire) Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
feat(profil-autora): sekcja osiągnięć z RAD-on OpenData (client-side, po ORCID)
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.
Cel
Faza 1 funkcji „edytowalny profil autora + przebudowa podstrony autora”.
Pełna specyfikacja (z sesji brainstormingu) w repo:
docs/superpowers/specs/2026-06-18-profil-autora-i-podstrona-design.md.Podstrona autora (
/autor/<pk|slug>/) przestaje być „metadane + jedenformularz wyszukiwania”, a staje się zestawem konfigurowalnych sekcji
(kolejność / widoczność / limit) renderowanych nad stałym nagłówkiem
tożsamości. Dane sekcji pochodzą z cache
Rekord/Autorzy/AuthorConnection.Co wchodzi w tej Fazie 1
Model
Autor:zdjecie(ImageField),biogram+biogram_format(md/html),uklad_profilu(JSONField),cached_property biogram_html.WybranaPublikacjaAutora(GenericFK do polimorficznej publikacji).0444.Logika (czysta, TDD)
bpp.util.biogram.renderuj_biogram: Markdown/HTML → bezpieczny HTML przeznowy
safe_biogram_html(bogatszy zestaw tagów niż wąski globalnysafe_html; usuwa treśćscript/style; linkirel="nofollow noopener").bpp.util.obrazy.przetworz_zdjecie_autora: EXIF → center-crop → WebP 400×400.bpp.profil_autora: rejestr 15 typów sekcji + walidacja i rozwiązywanieukładu (wymuszona wyszukiwarka, forward-compat dla nowych sekcji).
bpp.profil_autora_dane: buildery danych każdej sekcji + auto-ukrywaniepustych.
Render
AutorView: render sekcji wguklad_profilu(lub domyślnego, wariant„biogram-najpierw”; domyślnie ON także wykres publikacji w latach i
współautorzy) + linki do raportu autora (bieżący rok / ostatnie 4 lata /
szczegółowy formularz) pokazywane tylko gdy
DefinicjaRaportu(slug="raport-autorow").widoczny_dla(request).browse/autor.htmlprzebudowany: stały nagłówek (z awatarem) + pętla sekcji;formularz wyszukiwania wydzielony do
autor_sekcje/wyszukiwarka.html;partiale wszystkich sekcji; sekcja „kod do osadzenia” bez zmian.
AuthorConnection+ CTA do istniejącegowizualnego browsera sieci 2D/3D (bez nowej wizualizacji).
_autor-bem.scss.Admin
przetwarzanie i walidacja zdjęcia (≤5 MB → WebP) w
AutorForm.clean_zdjecie,inline wybranych publikacji.
Testy
39 nowych testów w
src/bpp/tests/test_profil/(TDD: czyste jednostki —biogram, zdjęcie, układ; modele; integracja widoku — render biogramu/
wyszukiwarki, ukrywanie sekcji, linki raportu public/inactive). Cała suita
test_profil+ istniejącetest_autor_autorzyzielone (43) na świeżymkontenerze — bez regresji.
manage.py checkczysty, pre-commit (ruff/djLint/TruffleHog) czysty.
make baseline-update(migracja0444zmienia schemat) — commitbaseline-sql/baseline.sql+baseline.meta.json. Świadomie nie robione wbranchu, żeby nie produkować konfliktów na wielkim pliku.
Świadomie poza zakresem (Faza 2, osobny PR)
Self-service edytor w „Mój profil” (drag-drop kolejności, przełączniki,
limity, upload zdjęcia z podglądem, live-preview biogramu, picker wyróżnionych
prac), eksport zbiorczy BibTeX/RIS. W Fazie 1 sekcja „eksport” oraz wypełnianie
zdjęcia/biogramu/układu działają przez Django admin.
🤖 Generated with Claude Code