feat(web): Core Refactor Phase A — extract sampling and cache modules; add adaptive TTL + eviction heuristics, Redis PoC, and metrics wiring. Tests added for TTL, eviction, exports, splash-adaptive, card index, and service worker. Docs+roadmap updated.

This commit is contained in:
matt 2025-09-24 13:57:23 -07:00
parent c4a7fc48ea
commit a029d430c5
49 changed files with 3889 additions and 701 deletions

View file

@ -74,8 +74,10 @@
{% if inspect and inspect.ok %}
<div class="two-col two-col-left-rail">
<aside class="card-preview card-sm" data-card-name="{{ selected }}">
<a href="https://scryfall.com/search?q={{ selected|urlencode }}" target="_blank" rel="noopener">
<img src="https://api.scryfall.com/cards/named?fuzzy={{ selected|urlencode }}&format=image&version=normal" alt="{{ selected }} card image" data-card-name="{{ selected }}" />
{# Strip synergy annotation for Scryfall search and image fuzzy param #}
{% set sel_base = (selected.split(' - Synergy (')[0] if ' - Synergy (' in selected else selected) %}
<a href="https://scryfall.com/search?q={{ sel_base|urlencode }}" target="_blank" rel="noopener">
<img src="https://api.scryfall.com/cards/named?fuzzy={{ sel_base|urlencode }}&format=image&version=normal" alt="{{ selected }} card image" data-card-name="{{ sel_base }}" />
</a>
</aside>
<div class="grow">

View file

@ -2,8 +2,10 @@
{# Step phases removed #}
<div class="two-col two-col-left-rail">
<aside class="card-preview" data-card-name="{{ commander.name }}">
<a href="https://scryfall.com/search?q={{ commander.name|urlencode }}" target="_blank" rel="noopener">
<img src="https://api.scryfall.com/cards/named?fuzzy={{ commander.name|urlencode }}&format=image&version=normal" alt="{{ commander.name }} card image" data-card-name="{{ commander.name }}" />
{# Strip synergy annotation for Scryfall search and image fuzzy param #}
{% set commander_base = (commander.name.split(' - Synergy (')[0] if ' - Synergy (' in commander.name else commander.name) %}
<a href="https://scryfall.com/search?q={{ commander_base|urlencode }}" target="_blank" rel="noopener">
<img src="https://api.scryfall.com/cards/named?fuzzy={{ commander_base|urlencode }}&format=image&version=normal" alt="{{ commander.name }} card image" data-card-name="{{ commander_base }}" />
</a>
</aside>
<div class="grow" data-skeleton>

View file

@ -2,8 +2,10 @@
{# Step phases removed #}
<div class="two-col two-col-left-rail">
<aside class="card-preview" data-card-name="{{ commander|urlencode }}">
<a href="https://scryfall.com/search?q={{ commander|urlencode }}" target="_blank" rel="noopener">
<img src="https://api.scryfall.com/cards/named?fuzzy={{ commander|urlencode }}&format=image&version=normal" alt="{{ commander }} card image" data-card-name="{{ commander }}" />
{# Ensure synergy annotation suffix is stripped for Scryfall query and image fuzzy param #}
{% set commander_base = (commander.split(' - Synergy (')[0] if ' - Synergy (' in commander else commander) %}
<a href="https://scryfall.com/search?q={{ commander_base|urlencode }}" target="_blank" rel="noopener">
<img src="https://api.scryfall.com/cards/named?fuzzy={{ commander_base|urlencode }}&format=image&version=normal" alt="{{ commander }} card image" data-card-name="{{ commander_base }}" />
</a>
</aside>
<div class="grow" data-skeleton>

View file

@ -2,8 +2,10 @@
{# Step phases removed #}
<div class="two-col two-col-left-rail">
<aside class="card-preview" data-card-name="{{ commander|urlencode }}">
<a href="https://scryfall.com/search?q={{ commander|urlencode }}" target="_blank" rel="noopener">
<img src="https://api.scryfall.com/cards/named?fuzzy={{ commander|urlencode }}&format=image&version=normal" alt="{{ commander }} card image" data-card-name="{{ commander }}" />
{# Strip synergy annotation for Scryfall search and image fuzzy param #}
{% set commander_base = (commander.split(' - Synergy (')[0] if ' - Synergy (' in commander else commander) %}
<a href="https://scryfall.com/search?q={{ commander_base|urlencode }}" target="_blank" rel="noopener">
<img src="https://api.scryfall.com/cards/named?fuzzy={{ commander_base|urlencode }}&format=image&version=normal" alt="{{ commander }} card image" data-card-name="{{ commander_base }}" />
</a>
</aside>
<div class="grow" data-skeleton>

View file

@ -2,9 +2,11 @@
{# Step phases removed #}
<div class="two-col two-col-left-rail">
<aside class="card-preview">
<a href="https://scryfall.com/search?q={{ commander|urlencode }}" target="_blank" rel="noopener">
<img src="https://api.scryfall.com/cards/named?fuzzy={{ commander|urlencode }}&format=image&version=normal" alt="{{ commander }} card image" data-card-name="{{ commander }}" loading="lazy" decoding="async" data-lqip="1"
srcset="https://api.scryfall.com/cards/named?fuzzy={{ commander|urlencode }}&format=image&version=small 160w, https://api.scryfall.com/cards/named?fuzzy={{ commander|urlencode }}&format=image&version=normal 488w, https://api.scryfall.com/cards/named?fuzzy={{ commander|urlencode }}&format=image&version=large 672w"
{# Strip synergy annotation for Scryfall search #}
<a href="https://scryfall.com/search?q={{ (commander.split(' - Synergy (')[0] if ' - Synergy (' in commander else commander)|urlencode }}" target="_blank" rel="noopener">
{% set commander_base = (commander.split(' - Synergy (')[0] if ' - Synergy (' in commander else commander) %}
<img src="https://api.scryfall.com/cards/named?fuzzy={{ commander_base|urlencode }}&format=image&version=normal" alt="{{ commander }} card image" data-card-name="{{ commander_base }}" loading="lazy" decoding="async" data-lqip="1"
srcset="https://api.scryfall.com/cards/named?fuzzy={{ commander_base|urlencode }}&format=image&version=small 160w, https://api.scryfall.com/cards/named?fuzzy={{ commander_base|urlencode }}&format=image&version=normal 488w, https://api.scryfall.com/cards/named?fuzzy={{ commander_base|urlencode }}&format=image&version=large 672w"
sizes="(max-width: 900px) 100vw, 320px" />
</a>
{% if status and status.startswith('Build complete') %}