mirror of
https://github.com/mwisnowski/mtg_python_deckbuilder.git
synced 2025-12-17 08:00:13 +01:00
fix(setup): restore security stamp filtering
This commit is contained in:
parent
f48e335e17
commit
4b3ddf5853
4 changed files with 70 additions and 27 deletions
|
|
@ -36,7 +36,7 @@ This format follows Keep a Changelog principles and aims for Semantic Versioning
|
||||||
- Preview performance CI check now waits for `/healthz` and retries theme catalog pagination fetches to dodge transient 500s during cold starts.
|
- Preview performance CI check now waits for `/healthz` and retries theme catalog pagination fetches to dodge transient 500s during cold starts.
|
||||||
|
|
||||||
### Fixed
|
### Fixed
|
||||||
- _No changes yet._
|
- Setup filtering now applies security-stamp exclusions case-insensitively so Acorn and Heart promo cards stay out of Commander-legal pools, with a regression test covering the behavior.
|
||||||
|
|
||||||
### Removed
|
### Removed
|
||||||
- Preview performance GitHub Actions workflow (`.github/workflows/preview-perf-ci.yml`) retired after persistent cold-start failures; run the regression helper script manually as needed.
|
- Preview performance GitHub Actions workflow (`.github/workflows/preview-perf-ci.yml`) retired after persistent cold-start failures; run the regression helper script manually as needed.
|
||||||
|
|
|
||||||
|
|
@ -1,31 +1,11 @@
|
||||||
# MTG Python Deckbuilder ${VERSION}
|
# MTG Python Deckbuilder ${VERSION}
|
||||||
|
|
||||||
## Summary
|
## Summary
|
||||||
- Introduced the Commander Browser with HTMX-powered pagination, theme surfacing, and direct Create Deck integration.
|
- Restored setup filtering to exclude Acorn and Heart promotional security stamps so Commander card pools stay format-legal.
|
||||||
- Shared color-identity macro and accessible theme chips power the new commander rows.
|
- Added a regression test that locks the security stamp filtering behavior in place.
|
||||||
- Manual QA walkthrough (desktop + mobile) recorded on 2025‑09‑30 with edge-case checks.
|
|
||||||
- Home dashboard aligns its quick actions with feature flags, exposing Commanders, Diagnostics, Random, Logs, and Setup where enabled.
|
|
||||||
|
|
||||||
## Added
|
## Added
|
||||||
- Commander browser skeleton page at `/commanders` with catalog-backed rows and accessible theme chips.
|
- Regression test covering security-stamp filtering during setup to guard against future case-sensitivity regressions.
|
||||||
- Documented QA checklist and results for the commander browser launch in `docs/qa/commander_browser_walkthrough.md`.
|
|
||||||
- Shared color-identity macro for reusable mana dots across commander rows and other templates.
|
|
||||||
- Home dashboard Commander/Diagnostics shortcuts gated by feature flags so all primary destinations have quick actions.
|
|
||||||
- Manual QA pass entered into project docs (2025-09-30) outlining desktop, mobile, and edge-case validations.
|
|
||||||
|
|
||||||
## Changed
|
|
||||||
- Commander list paginates in 20-item pages, with navigation controls mirrored above and below the results and automatic scroll-to-top.
|
|
||||||
- Commander hover preview shows card-only panel in browser context and removes the “+ more” overflow badge from theme chips.
|
|
||||||
- Content Security Policy upgrade directive ensures HTMX pagination requests remain HTTPS-safe behind proxies.
|
|
||||||
- Commander thumbnails adopt a fixed-width 160px frame (responsive on small screens) for consistent layout.
|
|
||||||
- Commander browser now separates name vs theme search, adds fuzzy theme suggestions, and tightens commander name matching to near-exact results.
|
|
||||||
- Commander search results stay put while filtering; typing no longer auto-scrolls the page away from the filter controls.
|
|
||||||
- Commander theme chips are larger, wrap cleanly, and display an accessible summary dialog when tapped on mobile.
|
|
||||||
- Theme dialogs now surface the full editorial description when available, improving longer summaries on small screens.
|
|
||||||
- Commander theme names unescape leading punctuation (e.g., +2/+2 Counters) so labels render without stray backslashes.
|
|
||||||
- Theme summary dialog also opens on desktop clicks, giving parity with mobile behavior.
|
|
||||||
- Mobile commander rows now feature larger thumbnails and a centered preview modal with expanded card art for improved readability.
|
|
||||||
- Preview performance CI check now waits for service health and retries catalog pagination fetches to smooth out transient 500s on cold boots.
|
|
||||||
|
|
||||||
## Fixed
|
## Fixed
|
||||||
- Documented friendly handling for missing `commander_cards.csv` data during manual QA drills to prevent white-screen failures.
|
- Setup filtering now applies security-stamp exclusions case-insensitively, preventing Acorn/Heart promo cards from entering Commander pools.
|
||||||
|
|
@ -194,13 +194,36 @@ def filter_dataframe(df: pd.DataFrame, banned_cards: List[str]) -> pd.DataFrame:
|
||||||
filtered_df = df.copy()
|
filtered_df = df.copy()
|
||||||
filter_config: FilterConfig = FILTER_CONFIG # Type hint for configuration
|
filter_config: FilterConfig = FILTER_CONFIG # Type hint for configuration
|
||||||
for field, rules in filter_config.items():
|
for field, rules in filter_config.items():
|
||||||
|
if field not in filtered_df.columns:
|
||||||
|
logger.warning('Skipping filter for missing field %s', field)
|
||||||
|
continue
|
||||||
|
|
||||||
for rule_type, values in rules.items():
|
for rule_type, values in rules.items():
|
||||||
|
if not values:
|
||||||
|
continue
|
||||||
|
|
||||||
if rule_type == 'exclude':
|
if rule_type == 'exclude':
|
||||||
for value in values:
|
for value in values:
|
||||||
filtered_df = filtered_df[~filtered_df[field].str.contains(value, na=False)]
|
mask = filtered_df[field].astype(str).str.contains(
|
||||||
|
value,
|
||||||
|
case=False,
|
||||||
|
na=False,
|
||||||
|
regex=False
|
||||||
|
)
|
||||||
|
filtered_df = filtered_df[~mask]
|
||||||
elif rule_type == 'require':
|
elif rule_type == 'require':
|
||||||
for value in values:
|
for value in values:
|
||||||
filtered_df = filtered_df[filtered_df[field].str.contains(value, na=False)]
|
mask = filtered_df[field].astype(str).str.contains(
|
||||||
|
value,
|
||||||
|
case=False,
|
||||||
|
na=False,
|
||||||
|
regex=False
|
||||||
|
)
|
||||||
|
filtered_df = filtered_df[mask]
|
||||||
|
else:
|
||||||
|
logger.warning('Unknown filter rule type %s for field %s', rule_type, field)
|
||||||
|
continue
|
||||||
|
|
||||||
logger.debug(f'Applied {rule_type} filter for {field}: {values}')
|
logger.debug(f'Applied {rule_type} filter for {field}: {values}')
|
||||||
|
|
||||||
# Remove illegal sets
|
# Remove illegal sets
|
||||||
|
|
|
||||||
40
code/tests/test_setup_filters.py
Normal file
40
code/tests/test_setup_filters.py
Normal file
|
|
@ -0,0 +1,40 @@
|
||||||
|
import pandas as pd
|
||||||
|
|
||||||
|
from file_setup.setup_utils import filter_dataframe
|
||||||
|
|
||||||
|
|
||||||
|
def _record(name: str, security_stamp: str) -> dict[str, object]:
|
||||||
|
return {
|
||||||
|
"name": name,
|
||||||
|
"faceName": name,
|
||||||
|
"edhrecRank": 100,
|
||||||
|
"colorIdentity": "G",
|
||||||
|
"colors": "G",
|
||||||
|
"manaCost": "{G}",
|
||||||
|
"manaValue": 1,
|
||||||
|
"type": "Creature",
|
||||||
|
"layout": "normal",
|
||||||
|
"text": "",
|
||||||
|
"power": "1",
|
||||||
|
"toughness": "1",
|
||||||
|
"keywords": "",
|
||||||
|
"side": "a",
|
||||||
|
"availability": "paper,arena",
|
||||||
|
"promoTypes": "",
|
||||||
|
"securityStamp": security_stamp,
|
||||||
|
"printings": "RNA",
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def test_filter_dataframe_removes_acorn_and_heart_security_stamps() -> None:
|
||||||
|
df = pd.DataFrame(
|
||||||
|
[
|
||||||
|
_record("Acorn Card", "Acorn"),
|
||||||
|
_record("Heart Card", "heart"),
|
||||||
|
_record("Legal Card", ""),
|
||||||
|
]
|
||||||
|
)
|
||||||
|
|
||||||
|
filtered = filter_dataframe(df, banned_cards=[])
|
||||||
|
|
||||||
|
assert list(filtered["name"]) == ["Legal Card"]
|
||||||
Loading…
Add table
Add a link
Reference in a new issue