Vydání verze 2.2.0: sjednocené popisky filtrů, váha prvku u komponent, ověření přihlášení před stahováním, zapamatované filtry s resetem a aktualizované README.
Plánovaný workflow api_monitor.yml (denně 05:17 UTC + ruční spuštění)
ověřuje kontrakt API, na kterém plugin závisí:
- tests/api_contract.py – stejné dotazy jako plugin, kontrola klíčů,
typů a tvarů odpovědí (OK / DRIFT / FAIL / UNAVAILABLE)
- tests/api_plugin_live.py – vlastní funkce pluginu (fetch_set,
load_amcr_data) proti živému API v qgis/qgis:ltr
- tests/api_monitor_report.py – jedno sledovací issue se štítkem
api-monitor; čistý běh ho zavře, výpadek ho nemění
Neběží na PR, aby výpadek digiarchivu neshodil PR. Popis v AGENTS.md,
OpenSpec změna add-daily-api-monitor.
Připraveno s pomocí AI (Claude), ověřeno proti produkčnímu API.
* Pamatovat filtry ve formuláři a přidat jejich reset (#84)
Filtrační dialog si do konce běhu QGIS pamatuje poslední filtry
potvrzené tlačítkem OK, zvlášť pro akce, lokality a samostatné
nálezy. Storno ani odmítnuté obrácené rozmezí uložený stav nemění.
- tlačítko „Obnovit výchozí“ vrátí formulář do výchozího stavu
(bbox zapnutý, PIAN se třemi úrovněmi); uložený stav změní až OK
- tlačítko ✕ u každého výběru vymaže jen tento filtr
- upozornění nahoře hlásí obnovené filtry a jejich počet
- kódy, které po aktualizaci heslářů zmizely, se zahodí; popisky
se skládají z aktuálních heslářů
- výchozí hodnoty jsou definované na jednom místě, PIAN už není
natvrdo v setup_picker()
- smoke test, README a changelog v2.2.0
OpenSpec: openspec/changes/add-filter-memory-and-reset/
Připraveno s pomocí AI (implementace subagent, revize a ověření
Claude), ručně zkontrolovat v QGIS.
* Křížek vrací filtr do výchozího stavu, oznámení bez ikony (#84)
Úpravy po ručním testu v QGIS:
- ✕ u výběru vrací filtr do jeho výchozího stavu; u PIAN – přesnost
obnoví tři předvolené úrovně, místo aby výběr vymazal. Tlačítko je
aktivní, jen když se výběr od výchozího liší. PIAN bez omezení jde
dál nastavit odškrtnutím všech úrovní ve výběru.
- oznámení o obnovených filtrech bez úvodního „ℹ“
Spec, design, tasks, README, changelog a smoke test upraveny.
Připraveno s pomocí AI.
* Archivovat OpenSpec změnu add-filter-memory-and-reset (#84)
Ruční test v QGIS (akce) zapsán k úkolu 4.3, změna archivována
do openspec/changes/archive/2026-10-02-add-filter-memory-and-reset/.
Připraveno s pomocí AI.
* Upřesnit záznam ručního testu u úkolu 4.3 (#84)
Vzhled i funkce ověřeny u všech tří typů dat, poslední oprava
(✕ u PIAN, oznámení) jen u akcí.
Připraveno s pomocí AI.
* fix: váha prvku komponent počítaná z komponent prošlých filtrem (#55)
Váha prvku_vaha = 1/n se dosud počítala ze všech komponent dokumentační
jednotky ještě před filtrem na období a areál, takže při aktivním filtru
váhy prvků jedné DJ nedávaly v součtu 1 (DJ se 4 komponentami, filtru
vyhoví 1 → váha 0,25 místo 1).
- nová funkce _component_entries: nejdřív vyfiltruje komponenty, pak
přidělí váhu 1/n z těch, které prošly; DJ bez komponent má váhu 1
- smoke test vaha_komponent (4×0,25; 1 ze 4 → 1; 2 ze 3 → 2×0,5; bez
komponent → 1)
- README: pole prvek_vaha v tabulce atributů komponent
- changelog v2.2.0 doplněn (bez povýšení verze)
- OpenSpec změna openspec/changes/fix-component-feature-weight
Ověřeno: živá data (Praha, novověk) – 0 z 1204 DJ se součtem vah ≠ 1,
původní kód 921; check_sources, bandit, detect-secrets, flake8, ruff,
pyqgis4-checker, smoke test v qgis/qgis:ltr i :stable.
Implementace připravena AI (Claude, subagent), ověřena a zkontrolována.
* openspec: archivovat fix-component-feature-weight (#55)
Ruční test v QGIS ověřen správcem: akce i lokality s Načíst komponenty,
bez filtru i s filtrem období – váhy prvků jedné DJ dávají součet 1 a
počítají se jen z vyfiltrovaných komponent. Úkol 3.2 odškrtnut, změna
archivována přes openspec archive --skip-specs.
Připraveno s pomocí AI (Claude).
* fix: před stahováním ověřit přihlášení přes islogged
Server při vypršelé session nevrací chybu, ale tiše odpoví jako
anonymnímu uživateli (jen přístupnost A). Plugin proto před stahováním
volá /api/user/islogged; při 'nologged' se jednou znovu přihlásí
z uložených údajů, a když to nejde, varuje v liště, že stahuje anonymně.
- amcr_tools: _check_islogged, _ensure_logged_in, volání v load_amcr_data
- smoke test: 7 offline scénářů stavu přihlášení
- README; changelog v2.2.0 v metadata.txt
- openspec/changes/fix-session-expiry-islogged: návrh, spec, design, úkoly
Closes#72. Připraveno s pomocí AI (Claude), ručně zkontrolováno.
* feat: odebrání přihlašovacích údajů uživatele i odhlásí
Dosud zůstala přihlášená session v paměti až do restartu QGIS, takže
se po „Odebrat uložené přihlašovací údaje“ dál stahovalo jako přihlášený.
Nově se session odhlásí na serveru (GET /api/user/logout) a zahodí;
když server neodpoví, zahodí se aspoň lokálně.
- amcr_tools: logout_from_api; amcr_dialog: volání v _forget_credentials
- smoke test: odhlášení, chyba sítě, bez session
- README, changelog v2.2.0, OpenSpec (požadavek + úkoly 2b; 3.3 ověřeno)
Připraveno s pomocí AI (Claude), ručně zkontrolováno.
* chore: archivovat OpenSpec změnu fix-session-expiry-islogged
Všechny úkoly hotové (2b.2 – odhlášení – ověřeno ručně v QGIS),
archivováno s --skip-specs (stupeň change-tracked, bez openspec/specs/).
Připraveno s pomocí AI (Claude), ručně zkontrolováno.
- amcr_tools.py: odstraněn UTF-8 BOM zanesený v 49fbd91 – kvůli němu
pyqgis4-checker soubor vůbec nezkontroloval a check_sources selhal
- check_version_bump.py: zalomen řádek nad 79 znaků (ruff E501)
- CITATION.cff: version 2.2.0 podle metadata.txt; date-released se
posune v den vydání
Připraveno s pomocí AI (Claude), ručně zkontrolováno.
* chore: odstranit resources.py a konfiguraci flake8 z balíčku
Scanner na plugins.qgis.org označil plugin jako „Validated
(configured)“ kvůli amcr_viewer/.flake8. Ten potlačoval jen stylové
nálezy (E302, E305, E501) ve vygenerovaném resources.py, který se
nikde neimportuje – ikony se načítají přímo z PNG. resources.py
repozitář pluginů nevyžaduje (validator.py v QGIS-Django, PyQGIS
cookbook: „optional“).
- Smazán amcr_viewer/resources.py a amcr_viewer/.flake8.
- CI: flake8 běží s --isolated (výchozí pravidla jako scanner);
kontrola ZIPu místo .flake8 hlídá povinný LICENSE.
- check_sources.py: žádné skryté soubory v balíčku, ani config
soubory scanneru.
- pyproject.toml, README.md, AGENTS.md: odstraněny odkazy na oba
soubory, popsán postup bez konfigurace.
Ověřeno: check_sources, flake8 7.3.0, ruff 0.16.5, bandit 1.9.4,
detect-secrets bez nálezů; pyqgis4-checker čistý; smoke test v QGIS
3.44.15 (Qt 5) i 4.2.3 (Qt 6); ZIP bez skrytých souborů.
Připraveno s pomocí AI (Claude).
* Verze 2.1.4
Povýšena verze v metadata.txt (+ changelog) a CITATION.cff po odstranění resources.py a konfigurace flake8.
Připraveno s pomocí AI (Claude).
Nová kontrola v release_pr_checks.yml ověří na PR směřujícím do main,
že verze v metadata.txt šla nahoru, první položka changelogu patří
nové verzi, CITATION.cff má stejnou verzi a posunuté date-released,
a že název release větve (version/vX.Y.Z) odpovídá verzi v metadata.txt.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013jT6Xv6FP2vWgBwLM57sc6
tests/check_sources.py hlídá pravidla, která nepotřebují QGIS a jejichž
porušení je tiché:
- UTF-8 BOM na začátku .py souboru. Pythonu ani QGISu nevadí, ale
oficiální pyqgis4-checker na něm spadne a soubor vůbec nezkontroluje,
takže rozbitý soubor vypadá čistě. Stalo se tady už dvakrát.
- přímý import z PyQt5/PyQt6 mimo shim qgis.PyQt
- spustitelná práva, skryté soubory a podezřelé typy souborů, které
hlásí analýza souborů na plugins.qgis.org
tests/smoke_test.py načte plugin ve skutečném QGIS, přečte scoped
enumy, vytvoří UpdateCodelistsTask a všechny tři filtrační dialogy
a ověří doplňování hraničního data. Běží offline a bez X serveru
(QT_QPA_PLATFORM=offscreen), takže nezávisí na dostupnosti API.
Očekávaná hodnota filtru je v testu napsaná natvrdo, ne přes
DATE_OPEN_TO. Porovnání proti konstantě z modulu dokazuje jen to, že se
modul shodne sám se sebou, a prošlo i s rozbitým sentinelem.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WhQyc1uQFcpkezLwM8if6T