Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
43 commits
Select commit Hold shift + click to select a range
400f87d
docs(profil-autora): spec edytowalnego profilu i przebudowy podstrony…
mpasternak Jun 18, 2026
0026429
feat(profil-autora): rdzeń — render biogramu, przetwarzanie zdjęcia, …
mpasternak Jun 18, 2026
65af2e0
feat(profil-autora): pola profilu na Autor + model WybranaPublikacjaA…
mpasternak Jun 18, 2026
9951f7f
feat(profil-autora): render konfigurowalnych sekcji podstrony + admin…
mpasternak Jun 18, 2026
b566f4a
style(profil-autora): ruff-format migracji 0444 (zgodność z CI lint)
mpasternak Jun 18, 2026
702a793
style(profil-autora): poprawna kolejność importów w autor.py (CI ruff)
mpasternak Jun 18, 2026
771e31c
docs(profil-autora): handoff + rewizja (2 kolumny, układ per-Uczelnia)
mpasternak Jun 19, 2026
8ab6c24
feat(profil-autora): układ per-Uczelnia + rejestr prawej kolumny + sz…
mpasternak Jun 19, 2026
d5e3154
feat(profil-autora): klik w całą pozycję listy prac (§3.4)
mpasternak Jun 19, 2026
065e394
feat(profil-autora): wykresy roczne — liniowy/słupkowy + PK + IF (§3.5)
mpasternak Jun 19, 2026
2a1ab94
feat(profil-autora): klikalne statystyki wg charakteru → wyszukiwarka…
mpasternak Jun 19, 2026
06ebb18
feat(profil-autora): historia zatrudnienia w lewej kolumnie (§3.7)
mpasternak Jun 19, 2026
f8049fd
feat(profil-autora): edytor układu na Uczelni + style 2-kolumnowe (§3…
mpasternak Jun 19, 2026
76338b0
fix(profil-autora): bezpieczna nawigacja listy prac (CodeQL js/url-re…
mpasternak Jun 19, 2026
92f0dd8
fix(profil-autora): klik w pozycję przez stretched-link zamiast JS (C…
mpasternak Jun 19, 2026
353ccb2
feat(profil-autora): self-service edycja biogramu i zdjęcia (§3.8, Fa…
mpasternak Jun 19, 2026
bb37ebb
test(fulltext): uniezależnij test od danych bazowych (Typ_Odpowiedzia…
mpasternak Jun 19, 2026
2f9194f
docs(profil-autora): handoff stanu (po §3.1–§3.8) + plan następnej sesji
mpasternak Jun 19, 2026
c36147c
feat(profil-autora): oś Y (maks + siatka) na wykresach rocznych (§3.1…
mpasternak Jun 19, 2026
0c5b596
feat(profil-autora): eksport BibTeX+RIS publikacji autora (§3.3)
mpasternak Jun 19, 2026
ed9b27f
Merge branch 'dev' of https://github.com/iplweb/bpp into feature/prof…
mpasternak Jun 19, 2026
5358aec
fix(migrations): merge dev 0444 + profil 0445 (leaf graph po scaleniu…
mpasternak Jun 19, 2026
d359451
feat(profil-autora): self-service picker wyróżnionych prac (§3.4)
mpasternak Jun 19, 2026
815fece
fix(profil-autora): czysty tekst opisów w pickerze wyróżnionych (§3.4…
mpasternak Jun 19, 2026
8bd4908
feat(profil-autora): kafelkowy edytor układu profilu w UczelniaAdmin …
mpasternak Jun 19, 2026
c94ec71
docs(profil-autora): status sesji nocnej (§3.1–§3.4 done + fix migrac…
mpasternak Jun 19, 2026
4ffc5fb
feat(profil-autora): 50/50 kolumny, klikalne zdjęcie, czystsza histor…
mpasternak Jun 20, 2026
ddae52b
fix(multiseek): etykieta charakteru formalnego w polu wyszukiwania
mpasternak Jun 20, 2026
9af835f
docs(profil-autora): opis funkcji w instrukcjach (użytkownik/administ…
mpasternak Jun 20, 2026
e8e1bcd
fix(profil-autora): picker wyróżnionych prac na Select2 (DAL ListSele…
mpasternak Jun 20, 2026
1fac65f
fix(profil-autora): modal zdjęcia, linki statystyk i układ lat na str…
mpasternak Jun 20, 2026
e00fa37
fix(nowe-raporty): „Raport szczegółowy" prefiluje autora w polu Select2
mpasternak Jun 20, 2026
b653503
feat(profil-autora): asynchroniczny eksport BibTeX/RIS przez Celery (…
mpasternak Jun 20, 2026
0a007c1
fix(profil-autora): autocomplete wyróżnionych prac szuka po pełnym op…
mpasternak Jun 20, 2026
1b165b0
fix(profil-autora): biogram opływa zdjęcie (float), bez pustego miejsca
mpasternak Jun 20, 2026
5ffddfc
feat(profil-autora): wyodrębnij bloki lewej kolumny do partiali sekcji
mpasternak Jun 20, 2026
034473d
feat(profil-autora): konfigurowalny układ obu kolumn (§3.2 rozszerzenie)
mpasternak Jun 20, 2026
c147894
Merge remote-tracking branch 'origin/dev' into feature/profil-autora
mpasternak Jul 6, 2026
02a929a
fix(profil-autora): nie nadpisuj None-em sentinela uczelni w AutorView
mpasternak Jul 6, 2026
5acbfe6
docs(spec): osiągnięcia autora z RAD-on OpenData (client-side, po ORCID)
mpasternak Jul 7, 2026
d6a974a
docs(spec): dodaj projekty/patenty/osiągnięcia z per-osobowych usług …
mpasternak Jul 7, 2026
1b052af
feat(profil-autora): sekcja osiągnięć z RAD-on (client-side, po ORCID)
mpasternak Jul 7, 2026
7598c91
Merge pull request #478 from iplweb/feat/radon-profil-autora
mpasternak Jul 8, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 37 additions & 0 deletions docs/administrator/ogolna.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,43 @@ Jeżeli chcesz później schować lub pokazać takie formularze, skorzystaj z op
Redagowanie➡Administracja➡Formularze wyszukiwania. Kliknij nazwę takiego
formularza, następnie zaznacz lub odznacz opcję "Publiczny" i zapisz rekord

#### Układ podstrony autora (profil autora) {#układ-podstrony-autora-profil-autora}

W rekordzie uczelni (Redagowanie➡Struktura➡Uczelnia, edycja rekordu) znajduje
się zwijana sekcja **„Profil autora (podstrona)"**. Zawiera ona **kafelkowy
edytor układu** prawej kolumny publicznych podstron autorów (patrz
[opis strony autora w instrukcji użytkownika](../uzytkownik/przegladanie-i-wyszukiwanie.md#strona-autora)).
Ustawienie jest **globalne dla całej uczelni** — obowiązuje na podstronach
wszystkich autorów.

Edytor działa następująco:

- każda dostępna sekcja prawej kolumny to osobny **kafelek**,
- **przeciągnij** kafelki (ang. *drag and drop*), aby zmienić ich kolejność,
- **odznacz checkbox** przy kafelku, aby ukryć daną sekcję,
- dla sekcji listowych ustaw **limit** liczby wyświetlanych pozycji
(do wyboru 10, 20, 30 lub 50).

!!! note
Lewa kolumna podstrony autora (zdjęcie, biogram, identyfikatory,
historia zatrudnienia, formularz wyszukiwania, przyciski eksportu itd.)
jest **stała** i nie podlega konfiguracji w tym edytorze.

!!! tip
**Pusty układ oznacza układ domyślny** — system pokaże rozsądny,
wbudowany zestaw sekcji. Nie trzeba niczego konfigurować, jeśli domyślny
układ jest wystarczający.

Wśród dostępnych sekcji prawej kolumny znajdują się m.in.: statystyki wg
charakteru formalnego, wykresy roczne (liczba publikacji / suma punktów MNiSW /
suma Impact Factor), najczęstsi współautorzy, najlepsze prace (wg punktacji
oraz wg Impact Factor), najnowsze artykuły, najnowsze książki i rozdziały,
ostatnio edytowane rekordy, dyscypliny, źródła oraz wyróżnione publikacje.

!!! note "Zrzut ekranu"
W tym miejscu można w przyszłości umieścić zrzut ekranu kafelkowego
edytora układu podstrony autora.

## Sposób kalkulacji dyscyplin

1. Dyscyplina i subdyscyplina naukowa przypisana autorowi na dany rok zawiera się w rekordzie `Autor_Dyscyplina`.
Expand Down
40 changes: 40 additions & 0 deletions docs/redaktor/autorzy.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,3 +29,43 @@ Algorytm ustalania aktualnego miejsca pracy działa w sposób następujący:
!!! warning

dany autor może mieć tylko jedno powiązanie oznaczone jako *Podstawowe miejsce pracy*.

## Zdjęcie i biogram autora (samodzielna edycja)

Zalogowany użytkownik powiązany ze swoim rekordem autora może **samodzielnie**
zredagować dane prezentowane na jego publicznej
[stronie autora](../uzytkownik/przegladanie-i-wyszukiwanie.md#strona-autora) —
bez pośrednictwa redaktora. Edycji podlegają:

- **biogram** — wpisywany w języku Markdown lub w HTML, z **podglądem na żywo**
(zmiany widać od razu obok pola edycji),
- **zdjęcie** — wgrane zdjęcie jest automatycznie kadrowane do kwadratu
i skalowane, zapisywane w formacie WebP; maksymalny rozmiar pliku to 5 MB.

Wejście do edycji: na górnej belce wybierz **„Mój profil"**, a następnie
**„Edytuj swoją stronę"** (adres `/bpp/profil/edycja/`).

!!! note
Te same pola (zdjęcie i biogram) redaktor może ustawić w module
redagowania, w rekordzie autora — przydatne, gdy autor nie edytuje
swoich danych samodzielnie.

## Wyróżnione publikacje autora

Autor może wskazać i uszeregować **wyróżnione prace**, które pojawią się na
początku jego [strony autora](../uzytkownik/przegladanie-i-wyszukiwanie.md#strona-autora)
— pod warunkiem, że uczelnia włączyła sekcję „wyróżnione publikacje" w układzie
podstrony (patrz
[układ podstrony autora](../administrator/ogolna.md#układ-podstrony-autora-profil-autora)).

Listę wyróżnionych prac edytuje się na stronie
`/bpp/profil/edycja/wybrane-publikacje/`:

- wyszukiwarka podpowiada pozycje do dodania,
- prace można **dodawać**, **usuwać** oraz **zmieniać ich kolejność**
(strzałkami).

!!! note
Wyszukiwarka podpowiada **wyłącznie własne prace autora** — autor może
wyróżnić tylko publikacje, z którymi jest powiązany.

309 changes: 309 additions & 0 deletions docs/superpowers/specs/2026-06-18-profil-autora-i-podstrona-design.md

Large diffs are not rendered by default.

183 changes: 183 additions & 0 deletions docs/superpowers/specs/2026-06-19-profil-autora-faza2-NEXT-HANDOFF.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,183 @@
# Profil autora — STATUS po rewizji 2-kol + §3.8 + HANDOFF do następnej sesji

Data: 2026-06-19
Dotyczy: PR **#385** (branch `feature/profil-autora` → `dev`).
Poprzednie dokumenty (czytaj dla kontekstu, w tej kolejności):
1. `docs/superpowers/specs/2026-06-19-profil-autora-rewizja-2col-HANDOFF.md` (rewizja 2-kol)
2. `docs/superpowers/specs/2026-06-18-profil-autora-i-podstrona-design.md` (spec bazowy)

> Ten dokument jest samowystarczalny. Świeża sesja ma z niego wznowić bez
> dostępu do poprzednich rozmów.

## STATUS — sesja nocna 2026-06-19/20 (autonomiczna, wszystko w PR #385)

Wykonane tej nocy (TDD, commit po commicie, każdy push z zielonym CI):

- **§3.1 kalibracja wykresów** — oś Y (etykieta maks + linie siatki) dla
wariantu liniowego i słupkowego. Zweryfikowane wizualnie. Commit `c36147c2b`.
- **§3.3 eksport BibTeX + RIS** — `/bpp/autor/<pk>/eksport.bib` (reuse
`bpp/export/bibtex.py`) i `/bpp/autor/<pk>/eksport.ris` (net-new
`bpp/export/ris.py`). Przyciski w lewej kolumnie. Limit `MAKS_EKSPORT=5000`.
Endpointy zweryfikowane na żywo. Commit `0c5b59605`.
- **§3.4 picker wyróżnionych prac** — self-service add/remove/reorder w
`/bpp/profil/edycja/wybrane-publikacje/`, autocomplete ograniczony do
WŁASNYCH prac autora, walidacja własności serwerowo na każdej akcji.
Zweryfikowane na żywo. Commity `d359451a4` + `815fecef5` (polish: striptags).
- **§3.2 edytor kafelkowy układu** — drag-drop (jquery-ui sortable z
Grappelli) w `UczelniaAdmin`: kafelek/sekcja z checkboxem widoczności +
selectem limitu, serializacja do `{"klucz","widoczna","limit"}`
(`waliduj_uklad`). Zweryfikowane wizualnie (14 kafelków). Commit `8bd49089c`.
- **FIX migracji** — `dev` dodał własną `0444_alter_uczelnia_…`, kolidującą
z profilowymi `0444`/`0445` (dwa liście grafu w stanie scalonym z dev, w
którym CI testuje PR). Scalono `dev` (czysto), dodano pustą migrację
scalającą `0446_merge_…`. Commity `ed9b27f41` (merge) + `5358aec94`.

Stan: 91 testów w `src/bpp/tests/test_profil/` zielonych na świeżym
kontenerze (pod scalonymi zależnościami: pytest 9, denorm 1.12.2). CI „Tests"
zielone na pośrednich pushach.

NADAL ODŁOŻONE (NIE robione): `make baseline-update` (przy scalaniu PR; teraz
doszły migracje 0444-dev + 0446-merge) oraz samo scalenie PR #385 → dev.
Drobiazg do poprawienia kiedyś: dokumentowany w CLAUDE.md autologin
`/__autologin__/?token=…` zwraca 404 (pakiet `django-dev-helpers` oczekuje
`?__autologin__=<token>`); w tej sesji obejście = mintowanie sesji DB.

## 0. Jak wznowić (środowisko)

- Worktree: `~/Programowanie/bpp-profil-autora`, branch `feature/profil-autora`.
**NIE twórz nowego worktree, NIE pracuj w `~/Programowanie/bpp`.**
- HEAD na chwilę pisania: `bb37ebbba`. Working tree czysty.
- Push (SSH nie działa; gh zalogowany jako `mpasternak`):
`git push https://github.com/iplweb/bpp.git feature/profil-autora:feature/profil-autora`
- Testy profilu: `PYTEST_TESTCONTAINERS_REUSE=1 uv run pytest src/bpp/tests/test_profil/`
- Gdy wyskoczy `bpp_uczelnia.site_id NOT NULL` (stale reuse-container) →
`make clean-testcontainers` i odpal bez `REUSE` (świeży kontener OK).
- Czyste logiki (bez DB) szybciej: `PYTEST_TESTCONTAINERS_DISABLE=1 uv run pytest ...`
- Po zmianach SCSS: `grunt build` (skompilowany CSS jest poza gitem —
commituj tylko źródła `.scss`).
- KAŻDY nowy `.py` (też migracje) → `uv run ruff format <plik>` przed commitem;
`pre-commit` (bez argumentów) musi być zielony.

## 1. Co JEST zrobione (CI w pełni zielone na #385)

Cała **rewizja 2-kolumnowa §3.1–§3.7** + **self-service §3.8** wdrożone TDD,
commit po commicie. Wszystkie realne gejty zielone (Build test-runner image,
12 shardów Tests, Lint changed files, CodeQL, baseline freshness, vitest),
`mergeStateStatus: CLEAN`.

Commity tej linii pracy (najnowszy u góry):
- `bb37ebbba` test(fulltext): uniezależnienie testu od danych bazowych
- `353ccb20c` §3.8 self-service edycja biogramu i zdjęcia
- `92f0dd81b` fix CodeQL: stretched-link zamiast JS-nawigacji
- `76338b03a` fix CodeQL: bezpieczna nawigacja (zastąpione przez stretched-link)
- `f8049fd38` §3.1 admin (edytor układu na Uczelni) + SCSS 2-kol
- `06ebb1872` §3.7 historia zatrudnienia (lewa kolumna)
- `2a1ab948c` §3.6 klikalne statystyki wg charakteru → wyszukiwarka
- `065e394d7` §3.5 wykresy roczne (liniowy/słupkowy) + PK + IF
- `d5e3154b7` §3.4 klik w całą pozycję listy prac
- `8ab6c24a2` §3.1+§3.2+§3.3 układ per-Uczelnia + rejestr prawej kol + szablon 2-kol
- (Faza 1: `00264292e`, `65af2e00b`, `9951f7fb5`, `400f87d5c`, …)

### 1.1. Architektura — gdzie co jest
- Układ profilu = **globalny per-Uczelnia**: `Uczelnia.uklad_profilu_autora`
(JSONField). `Autor.uklad_profilu` USUNIĘTE. Migracja `0445`.
- `bpp/profil_autora.py` — rejestr `KATALOG_SEKCJI` = **tylko PRAWA kolumna**
(15 typów, bez `obowiazkowa`). `rozwiaz_uklad(uczelnia)`.
- `bpp/profil_autora_dane.py` — buildery + `przygotuj_sekcje(autor, uczelnia,
request)`; helper `_agreguj_po_latach`. Nowe buildery `_wykres_pk_lata`,
`_wykres_if_lata` (IF auto-hide gdy suma=0).
- `bpp/views/browse.py` `AutorView` — przekazuje `uczelnia` do `przygotuj_sekcje`;
`BuildSearch.post` obsługuje `charakter_formalny` (przez
`CharakterFormalnyQueryObject`, rozwiązuje po **nazwie**, nie pk).
- `bpp/templates/browse/autor.html` — 2 kolumny (Foundation grid w HTML):
lewa `cell large-4` (stała: zdjęcie→biogram→jednostka→historia
zatrudnienia→identyfikatory→metryki→stopnie→opis→cytowania→wyszukiwarka→
raport), prawa `cell large-8` (pętla `sekcje_profilu`). Embed pełna szerokość
pod gridem.
- Partiale sekcji: `browse/autor_sekcje/*.html`. Współdzielone:
`_lista_prac.html` (stretched-link), `_wykres_lata.html` (liniowy>10 /
słupkowy≤10), `_historia_zatrudnienia.html`.
- `Autor.historia_zatrudnienia()` — `bpp/models/autor.py`.
- Admin: edytor układu (JSON textarea) w `UczelniaAdmin` (fieldset „Profil
autora (podstrona)"); `uklad_profilu` zniknęło z `AutorAdmin`.
- **§3.8 self-service**: `bpp/views/profil_edycja.py` (`ProfilEdycjaView`,
`AutorProfilForm`, `WymagajAutoraMixin`, `ProfilBiogramPodgladView`); URL-e
`bpp:profil-edycja`, `bpp:profil-biogram-podglad`; szablon
`bpp/profil_edycja.html` (live preview, debounce, CSRF); link „Edytuj swoją
stronę" na `bpp/profil_uzytkownika.html`. Autor edytuje TYLKO biogram+zdjęcie.
- Style: `bpp/static/scss/_autor-bem.scss` (2-kol, stretched-link + line-clamp,
wykres liniowy SVG, statystyki-link, historia).
- Testy: `src/bpp/tests/test_profil/` (test_uklad, test_models, test_widok,
test_lista_prac, test_wykresy, test_statystyki, test_historia, test_admin,
test_profil_edycja, test_biogram, test_obrazy) — 60 zielonych (świeży kontener).

### 1.2. Lekcje / pułapki (żeby nie powtarzać)
- **CodeQL `js/xss-through-dom`**: zapis wartości z DOM do `window.location`
jest sinkiem (możliwy `javascript:`). Dlatego klik w pozycję listy prac
zrobiony jest jako **stretched-link** (pusta nakładka `<a>`), bez JS.
- **§3.6**: `CharakterFormalnyQueryObject.value_from_web` rozwiązuje po
**`nazwa`** (MPTT z potomkami), NIE po pk. Formularz statystyk POST-uje
`autor=<pk>` + `charakter_formalny=<nazwa>`.
- **pytest-split / shardy**: dodanie testów zmienia podział na shardy i może
ujawnić testy zależne od danych bazowych, które poprzedzający test
transakcyjny wyczyścił (`flush`). Każdy test musi deklarować WSZYSTKIE swoje
zależności na danych referencyjnych (np. `typy_odpowiedzialnosci`).
- **CI**: realne gejty to `Build test-runner image` + `Tests (sharded)` (12
shardów). Szybkie „success" <1 min = skip, nie dowód. Czytaj uważnie.

## 2. Świadomie ODŁOŻONE (decyzja użytkownika 2026-06-19)
- **`make baseline-update`** — NIE robić teraz. Do zrobienia **raz, przy
scalaniu** (migracje 0444 + 0445; commit `baseline-sql/baseline.sql` +
`baseline.meta.json`). NIE w równoległych branchach.
- **Scalenie / domknięcie PR #385** — nie teraz.

## 3. Co DALEJ (kandydaci na następną sesję; wybrać z użytkownikiem)

Kolejność = sugerowany priorytet. Każdy punkt to osobny, niezależny kawałek.

### 3.1. Wizualna weryfikacja strony (NISKI koszt, WYSOKA wartość) — REKOMENDOWANE NAJPIERW
Duża przebudowa UI poszła bez ani jednego spojrzenia w przeglądarkę.
- `uv run run-site run` (lub `--no-browser` w tle), wejść na `/bpp/autor/<pk>/`
autora z publikacjami, zdjęciem, biogramem i historią zatrudnienia.
- Sprawdzić: 2 kolumny na desktopie i stackowanie na mobile; stretched-link
(klik w pozycję działa, link DOI w opisie też); line-clamp opisu; wykres
liniowy (>10 lat) vs słupkowy (≤10); klik w charakter → multiseek; embed pod
gridem; `/profil/edycja/` (upload zdjęcia, live preview biogramu).
- Skalibrować wartości wstępne: próg „10 lat" wykresu, liczba linii line-clamp
(teraz 3), szerokości kolumn. To było zaznaczone jako „do kalibracji
wizualnej".

### 3.2. Edytor kafelkowy układu w `UczelniaAdmin` (drag-drop)
Teraz MVP = JSON w textarea (`uklad_profilu_autora`). Docelowo ładny UI:
lista sekcji z checkbox widoczności + select limitu + drag-drop kolejności,
serializacja do tego samego JSON-a. **Najpierw sprawdzić istniejący JS
sortowania w repo** (jest `sortable_field_name` w inline'ach adminów) zanim
dołożysz zależność. Reużyć `waliduj_uklad`/`KATALOG_SEKCJI` z `profil_autora.py`.

### 3.3. Eksport zbiorczy publikacji autora (BibTeX + RIS)
- BibTeX: reużycie `src/bpp/export/bibtex.py` (`export_to_bibtex`,
`.to_bibtex()` na `.original`). Endpoint `/autor/<pk>/eksport.bib`.
- **RIS — net-new** (nie istnieje). Endpoint `/autor/<pk>/eksport.ris`.
- Świadomy limit/stream dla autorów z dużą liczbą prac.
- Sekcja `eksport` została USUNIĘTA z rejestru w rewizji — eksport wpiąć jako
przyciski (lewa kolumna lub osobny blok), nie jako sekcję prawej kolumny.

### 3.4. Self-service: picker wyróżnionych prac (`WybranaPublikacjaAutora`)
Model + inline w adminie już są (Faza 1). Brakuje self-service: autor
dodaje/usuwa/sortuje wyróżnione prace (autocomplete) w `/profil/edycja/`.
Sekcja `wybrane_publikacje` w rejestrze jest domyślnie OFF — uczelnia może ją
włączyć w układzie.

### 3.5. Drobny polish (opcjonalnie)
- `_lista_prac.html`: `aria-label` nakładki jest generyczny („Szczegóły
publikacji") — można wstawić tytuł pracy.
- `profil_edycja.html`: dodać help/skrót składni Markdown przy biogramie.
- Sprawdzić render `opis` vs `biogram` w lewej kolumnie (oba mogą być widoczne).

## 4. Reguły wykonania (z CLAUDE.md — trzymać się)
- TDD: test → patrz jak failuje → implementuj. Commit po commicie.
- Max 88 znaków (ruff). Komentarze django `{# #}` jedno-liniowe.
- Ikony: frontend publiczny → Foundation-Icons; admin → emoji.
- NIE nadpisywać klas grid Foundation w SCSS — zmieniać klasy w HTML.
- NIE edytować istniejących migracji. Nowa = `0446+`.
- `pre-commit` bez argumentów; fixy ręcznie (NIE `ruff --fix` batch).
Loading