feat: add keyword normalization and protection grant detection, fix template syntax and polling issues

This commit is contained in:
matt 2025-10-08 20:59:51 -07:00
parent 86ec68acb4
commit 06d8796316
17 changed files with 1692 additions and 611 deletions

View file

@ -170,7 +170,7 @@ def _step5_summary_placeholder_html(token: int, *, message: str | None = None) -
return (
f'<div id="deck-summary" data-summary '
f'hx-get="/build/step5/summary?token={token}" '
'hx-trigger="load, step5:refresh from:body" hx-swap="outerHTML">'
'hx-trigger="step5:refresh from:body" hx-swap="outerHTML">'
f'<div class="muted" style="margin-top:1rem;">{_esc(text)}</div>'
'</div>'
)

View file

@ -1181,6 +1181,9 @@ def _ensure_setup_ready(out, force: bool = False) -> None:
# Only flip phase if previous run finished
if st.get('phase') in {'themes','themes-fast'}:
st['phase'] = 'done'
# Also ensure percent is 100 when done
if st.get('finished_at'):
st['percent'] = 100
with open(status_path, 'w', encoding='utf-8') as _wf:
json.dump(st, _wf)
except Exception:
@ -1463,16 +1466,17 @@ def _ensure_setup_ready(out, force: bool = False) -> None:
except Exception:
pass
# Unconditional fallback: if (for any reason) no theme export ran above, perform a fast-path export now.
# This guarantees that clicking Run Setup/Tagging always leaves themes current even when tagging wasn't needed.
# Conditional fallback: only run theme export if refresh_needed was True but somehow no export performed.
# This avoids repeated exports when setup is already complete and _ensure_setup_ready is called again.
try:
if not theme_export_performed:
if not theme_export_performed and refresh_needed:
_refresh_theme_catalog(out, force=False, fast_path=True)
except Exception:
pass
else: # If export just ran (either earlier or via fallback), ensure enrichment ran (safety double-call guard inside helper)
try:
_run_theme_metadata_enrichment(out)
if theme_export_performed or refresh_needed:
_run_theme_metadata_enrichment(out)
except Exception:
pass

View file

@ -309,7 +309,8 @@
.catch(function(){ /* noop */ });
} catch(e) {}
}
setInterval(pollStatus, 3000);
// Poll every 10 seconds instead of 3 to reduce server load (only for header indicator)
setInterval(pollStatus, 10000);
pollStatus();
// Health indicator poller

View file

@ -462,11 +462,12 @@
<!-- controls now above -->
{% if allow_must_haves %}
{% include "partials/include_exclude_summary.html" with oob=False %}
{% set oob = False %}
{% include "partials/include_exclude_summary.html" %}
{% endif %}
<div id="deck-summary" data-summary
hx-get="/build/step5/summary?token={{ summary_token }}"
hx-trigger="load, step5:refresh from:body"
hx-trigger="load once, step5:refresh from:body"
hx-swap="outerHTML">
<div class="muted" style="margin-top:1rem;">
{% if summary_ready %}Loading deck summary…{% else %}Deck summary will appear after the build completes.{% endif %}

View file

@ -127,7 +127,8 @@
.then(update)
.catch(function(){});
}
setInterval(poll, 3000);
// Poll every 5 seconds instead of 3 to reduce server load
setInterval(poll, 5000);
poll();
})();
</script>