feat: add Settings live stream analysis button and diagnose Laya batch failure (#14)

Add a Settings action to manually rerun Live TV stream analysis:
it triggers an admin-guarded projection rebuild endpoint that
groups streams into logical channels (covering channels present
before the projection existed) and reruns language/Laya detection,
with progress presented via liveAnalysisPresentation. Harden the
Laya batch path that failed with 'Local AI language matching
failed' by surfacing the underlying cause and falling back to
standard matching cleanly. Guard admin-only rebuild through a new
authz helper and cover routes, service and presentation with tests.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
blomios
2026-10-02 16:09:13 +02:00
parent 9116d90526
commit 67d9869364
14 changed files with 386 additions and 25 deletions

View File

@ -10,7 +10,7 @@
<title>nodecast-tv | IPTV Player</title>
<meta name="description" content="Stream live TV, movies, and series with EPG support">
<link rel="icon" type="image/svg+xml" href="/favicon.svg">
<link rel="stylesheet" href="css/main.css?v=7">
<link rel="stylesheet" href="css/main.css?v=8">
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&family=Outfit:wght@800&display=swap"
@ -469,6 +469,26 @@
<div class="channel-matching-settings">
<h4>Channel matching</h4>
<p class="setting-hint">Choose how Nodecast TV identifies matching streams and languages.</p>
<div class="live-analysis-panel" id="live-analysis-panel">
<div class="live-analysis-heading">
<div>
<strong>Channel analysis</strong>
<div class="setting-hint">Group matching streams into channels and update detected languages.</div>
</div>
<button type="button" class="btn btn-primary" id="live-analysis-button">Analyze channels</button>
</div>
<p class="setting-hint">Use this to analyze channels that were added before automatic analysis was enabled.</p>
<div id="live-analysis-status" class="setting-hint" role="status">Checking status…</div>
<div id="live-analysis-progress" class="laya-progress" hidden>
<div id="live-analysis-progress-track" class="laya-progress-track" role="progressbar" aria-label="Channel analysis progress">
<span id="live-analysis-progress-bar" class="laya-progress-bar"></span>
</div>
<div id="live-analysis-progress-text" class="setting-hint"></div>
</div>
<div id="live-analysis-fallback" class="setting-hint"></div>
<button type="button" class="btn btn-ghost laya-details-toggle" id="live-analysis-details-toggle" aria-expanded="false" hidden>Show details</button>
<pre id="live-analysis-error-details" class="laya-error-details" hidden></pre>
</div>
<div class="matching-mode-options">
<label class="matching-mode-card">
<input type="radio" name="language-detection-mode" value="algo" checked>
@ -1185,6 +1205,7 @@
<script src="/js/services/channelLanguageDetection.js?v=1"></script>
<script src="/js/services/channelLanguageFusion.js?v=1"></script>
<script src="/js/services/layaStatusPresentation.js?v=4"></script>
<script src="/js/services/liveAnalysisPresentation.js?v=1"></script>
<script src="/js/services/liveChannelProjection.js?v=1"></script>
<script src="/js/services/channelVariantGrouping.js?v=6"></script>
<script src="/js/components/ChannelList.js?v=11"></script>
@ -1195,7 +1216,7 @@
<script src="/js/pages/Guide.js?v=2"></script>
<script src="/js/pages/MoviesPage.js?v=4"></script>
<script src="/js/pages/SeriesPage.js?v=1"></script>
<script src="/js/pages/Settings.js?v=7"></script>
<script src="/js/pages/Settings.js?v=8"></script>
<script src="/js/pages/WatchPage.js?v=1"></script>
<script src="/js/app.js?v=4"></script>
<script>