Files
khadhroony-bot3/kb-app-demo-desktop/frontend/demo_sql_replay_candidates.html
2026-07-25 23:57:48 +02:00

444 lines
36 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!-- file: kb_app_demo/frontend/demo_sql_replay_candidates.html -->
<!-- version: 6 -->
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Khadhroony Bot3 - Candidats de replay SQL</title>
<link rel="stylesheet" href="sass/main.scss" />
</head>
<body class="bg-body-tertiary">
<header class="app-header">
<nav class="navbar navbar-expand-lg h-100 py-0 bg-light text-dark">
<div class="container-fluid px-4 my-0">
<div class="navbar-brand d-flex align-items-center">
<img alt="Logo" src="imgs/logo.png" class="app-logo" />
<span class="ps-2 fs-4 fw-bold text-primary font-logo">Candidats de replay SQL</span>
</div>
<div class="ms-auto d-flex align-items-center gap-2">
<span id="replayCandidateProfileBadge" class="badge text-bg-info">Profil —</span>
<span id="replayCandidateStatusBadge" class="badge text-bg-secondary">Initialisation</span>
<button id="openCoreExtractionButton" class="btn btn-sm btn-outline-primary" type="button">Ouvrir extraction core</button>
</div>
</div>
</nav>
</header>
<main class="app-main">
<div class="osb-scrollable pt-1 pb-4" data-simplebar>
<div class="container-fluid px-4 py-4">
<div class="card shadow-sm border-0 mb-4">
<div class="card-body">
<h1 class="h3 card-title">Exploration read-only des candidats</h1>
<p class="text-body-secondary mb-2">Les requêtes sont paramétrées, bornées et sans SQL libre. Utilisez les cases à cocher pour sélectionner les lignes. La case du header sélectionne ou désélectionne toutes les lignes correspondant au filtre local. Sans sélection explicite, la copie et lexport CSV utilisent toutes les lignes filtrées. Les CSV UTF-8 avec BOM et séparateur point-virgule sont écrits par le backend Tauri dans <code>./data/exports_csv/</code>. LibreOffice Calc peut toujours afficher son dialogue dimport, car le format CSV ne décrit pas formellement son encodage ni son séparateur.</p>
<div class="small text-body-secondary">
<span class="fw-semibold">DSN :</span>
<code id="replayCandidateDsn"></code>
<span class="ms-3 fw-semibold">Limite serveur maximale :</span>
<code id="replayCandidateMaximumLimit"></code>
</div>
</div>
</div>
<ul class="nav nav-tabs mb-3" id="replayCandidateTabs" role="tablist">
<li class="nav-item" role="presentation">
<button class="nav-link active" id="transactionsTabButton" data-bs-toggle="tab" data-bs-target="#transactionsTabPane" type="button" role="tab" aria-controls="transactionsTabPane" aria-selected="true">Transactions et signatures</button>
</li>
<li class="nav-item" role="presentation">
<button class="nav-link" id="programsTabButton" data-bs-toggle="tab" data-bs-target="#programsTabPane" type="button" role="tab" aria-controls="programsTabPane" aria-selected="false">Programmes</button>
</li>
<li class="nav-item" role="presentation">
<button class="nav-link" id="mintsTabButton" data-bs-toggle="tab" data-bs-target="#mintsTabPane" type="button" role="tab" aria-controls="mintsTabPane" aria-selected="false">Mints</button>
</li>
<li class="nav-item" role="presentation">
<button class="nav-link" id="ownersTabButton" data-bs-toggle="tab" data-bs-target="#ownersTabPane" type="button" role="tab" aria-controls="ownersTabPane" aria-selected="false">Owners</button>
</li>
<li class="nav-item" role="presentation">
<button class="nav-link" id="accountsTabButton" data-bs-toggle="tab" data-bs-target="#accountsTabPane" type="button" role="tab" aria-controls="accountsTabPane" aria-selected="false">Comptes</button>
</li>
</ul>
<div class="tab-content" id="replayCandidateTabContent">
<section class="tab-pane fade show active" id="transactionsTabPane" role="tabpanel" aria-labelledby="transactionsTabButton" tabindex="0">
<div class="card shadow-sm border-0 mb-4">
<div class="card-body">
<h2 class="h5 card-title">Filtres PostgreSQL bornés</h2>
<div class="row g-3 align-items-end">
<div class="col-12 col-xl-4">
<label for="transactionSignatureContainsInput" class="form-label">Signature contient</label>
<input id="transactionSignatureContainsInput" class="form-control font-monospace" type="text" autocomplete="off" />
</div>
<div class="col-6 col-md-3 col-xl-2">
<label for="transactionMinSlotInput" class="form-label">Slot minimum</label>
<input id="transactionMinSlotInput" class="form-control" type="number" min="0" step="1" />
</div>
<div class="col-6 col-md-3 col-xl-2">
<label for="transactionMaxSlotInput" class="form-label">Slot maximum</label>
<input id="transactionMaxSlotInput" class="form-control" type="number" min="0" step="1" />
</div>
<div class="col-6 col-md-3 col-xl-2">
<label for="transactionRawStateSelect" class="form-label">État raw</label>
<select id="transactionRawStateSelect" class="form-select">
<option value="">Tous</option>
<option value="received">received</option>
<option value="core_extracted">core_extracted</option>
<option value="decoded">decoded</option>
<option value="materialized">materialized</option>
<option value="failed">failed</option>
</select>
</div>
<div class="col-6 col-md-3 col-xl-2">
<label for="transactionLedgerStatusSelect" class="form-label">Ledger core</label>
<select id="transactionLedgerStatusSelect" class="form-select">
<option value="">Tous</option>
<option value="not_started">not_started</option>
<option value="running">running</option>
<option value="succeeded">succeeded</option>
<option value="failed">failed</option>
</select>
</div>
<div class="col-12 col-xl-5">
<label for="transactionProgramIdInput" class="form-label">Program ID exact</label>
<input id="transactionProgramIdInput" class="form-control font-monospace" type="text" list="knownProgramDatalist" autocomplete="off" />
</div>
<div class="col-6 col-md-3 col-xl-2">
<label for="transactionProgramScopeSelect" class="form-label">Portée programme</label>
<select id="transactionProgramScopeSelect" class="form-select">
<option value="any">outer + inner + logs</option>
<option value="outer">outer uniquement</option>
<option value="inner">inner uniquement</option>
<option value="logs">logs liés uniquement</option>
</select>
</div>
<div class="col-6 col-md-3 col-xl-2">
<label for="transactionEntityKindSelect" class="form-label">Type dentité</label>
<select id="transactionEntityKindSelect" class="form-select">
<option value="">Aucune</option>
<option value="mint">mint</option>
<option value="owner">owner</option>
<option value="account_key">account_key</option>
</select>
</div>
<div class="col-12 col-xl-3">
<label for="transactionEntityValueInput" class="form-label">Entité exacte</label>
<input id="transactionEntityValueInput" class="form-control font-monospace" type="text" autocomplete="off" />
</div>
<div class="col-6 col-md-3 col-xl-1">
<label for="transactionLimitInput" class="form-label">Limite</label>
<input id="transactionLimitInput" class="form-control" type="number" min="1" max="5000" step="1" value="500" />
</div>
<div class="col-6 col-md-3 col-xl-2">
<div class="form-check form-switch mb-2">
<input id="transactionNewestFirstInput" class="form-check-input" type="checkbox" role="switch" checked />
<label class="form-check-label" for="transactionNewestFirstInput">Plus récents dabord</label>
</div>
</div>
<div class="col-12 col-xl-3">
<div class="d-grid d-sm-flex gap-2">
<button id="resetTransactionsButton" class="btn btn-outline-secondary" type="button">Réinitialiser</button>
<button id="loadTransactionsButton" class="btn btn-primary flex-grow-1" type="button">Charger les transactions</button>
</div>
</div>
</div>
</div>
</div>
<div class="card shadow-sm border-0">
<div class="card-body">
<div class="d-flex flex-wrap justify-content-between align-items-center gap-2 mb-3">
<div>
<h2 class="h5 card-title mb-1">Transactions candidates</h2>
<div id="transactionResultSummary" class="small text-body-secondary">Aucune requête exécutée.</div>
</div>
<div>
<div class="btn-group flex-wrap" role="group" aria-label="Actions signatures">
<button id="copySignaturesButton" class="btn btn-sm btn-outline-primary" type="button">Copier signatures multiligne</button>
<button id="exportTransactionsCsvButton" class="btn btn-sm btn-outline-success" type="button">Exporter CSV</button>
</div>
<div class="small text-body-secondary mt-1">Les identifiants longs sont tronqués à lécran. Survolez-les pour afficher leur valeur complète ou utilisez le bouton de copie individuel.</div>
</div>
</div>
<div class="table-responsive">
<table id="transactionCandidateTable" class="table table-striped table-hover table-sm align-middle w-100">
<thead>
<tr>
<th class="replay-select-column"><span class="visually-hidden">Sélection</span></th>
<th>Signature</th>
<th>Slot</th>
<th>Raw</th>
<th title="État de présence core ; échec on-chain signifie que la transaction Solana a échoué, pas que lextraction core a échoué.">Core</th>
<th>Ledger</th>
<th>Version</th>
<th>Essais</th>
<th data-bs-toggle="tooltip" title="Nombre total dinstructions top-level.">Outer inst.</th>
<th data-bs-toggle="tooltip" title="Nombre total dinstructions internes.">Inner inst.</th>
<th data-bs-toggle="tooltip" title="Nombre de program IDs distincts dans les instructions top-level.">Outer pr.</th>
<th data-bs-toggle="tooltip" title="Nombre de program IDs distincts dans les instructions internes.">Inner pr.</th>
<th>Mise à jour</th>
</tr>
</thead>
</table>
</div>
</div>
</div>
</section>
<section class="tab-pane fade" id="programsTabPane" role="tabpanel" aria-labelledby="programsTabButton" tabindex="0">
<div class="card shadow-sm border-0 mb-4">
<div class="card-body">
<div class="row g-3 align-items-end">
<div class="col-12 col-lg-5">
<label for="knownProgramSelect" class="form-label">Programme connu (kb_program_ids)</label>
<select id="knownProgramSelect" class="form-select">
<option value="">Tous les programmes connus</option>
</select>
</div>
<div class="col-12 col-lg-4">
<label for="programContainsInput" class="form-label">Program ID contient</label>
<input id="programContainsInput" class="form-control font-monospace" type="text" list="knownProgramDatalist" autocomplete="off" />
</div>
<div class="col-6 col-lg-1">
<label for="programLimitInput" class="form-label">Limite</label>
<input id="programLimitInput" class="form-control" type="number" min="1" max="5000" step="1" value="500" />
</div>
<div class="col-12 col-lg-2">
<div class="d-grid gap-2">
<button id="resetProgramsButton" class="btn btn-outline-secondary" type="button">Réinitialiser</button>
<button id="loadProgramsButton" class="btn btn-primary" type="button">Charger les programmes</button>
</div>
</div>
</div>
</div>
</div>
<div class="card shadow-sm border-0">
<div class="card-body">
<div class="d-flex flex-wrap justify-content-between align-items-center gap-2 mb-3">
<div>
<h2 class="h5 card-title mb-1">Programmes indexés</h2>
<div id="programResultSummary" class="small text-body-secondary">Aucune requête exécutée.</div>
</div>
<div>
<div class="btn-group flex-wrap" role="group" aria-label="Actions programmes">
<button id="useSelectedProgramButton" class="btn btn-sm btn-outline-secondary" type="button">Utiliser comme filtre transactions</button>
<button id="copyProgramsButton" class="btn btn-sm btn-outline-primary" type="button">Copier IDs multiligne</button>
<button id="exportProgramsCsvButton" class="btn btn-sm btn-outline-success" type="button">Exporter CSV</button>
</div>
<div class="small text-body-secondary mt-1">Cochez un programme. Sans sélection, laction accepte une seule ligne restant après le filtre local.</div>
</div>
</div>
<div class="table-responsive">
<table id="programCandidateTable" class="table table-striped table-hover table-sm align-middle w-100">
<thead>
<tr>
<th class="replay-select-column"><span class="visually-hidden">Sélection</span></th>
<th>Code connu</th>
<th>Program ID</th>
<th>Transactions</th>
<th>Outer</th>
<th>Inner</th>
<th>Logs liés</th>
<th>Slot min</th>
<th>Slot max</th>
</tr>
</thead>
</table>
</div>
</div>
</div>
</section>
<section class="tab-pane fade" id="mintsTabPane" role="tabpanel" aria-labelledby="mintsTabButton" tabindex="0">
<div class="card shadow-sm border-0 mb-4">
<div class="card-body">
<div class="row g-3 align-items-end">
<div class="col-12 col-lg-7">
<label for="mintContainsInput" class="form-label">Mint contient</label>
<input id="mintContainsInput" class="form-control font-monospace" type="text" autocomplete="off" />
</div>
<div class="col-6 col-lg-2">
<label for="mintLimitInput" class="form-label">Limite</label>
<input id="mintLimitInput" class="form-control" type="number" min="1" max="5000" step="1" value="500" />
</div>
<div class="col-12 col-lg-3">
<div class="d-grid d-sm-flex gap-2">
<button id="resetMintsButton" class="btn btn-outline-secondary" type="button">Réinitialiser</button>
<button id="loadMintsButton" class="btn btn-primary flex-grow-1" type="button">Charger les mints</button>
</div>
</div>
</div>
</div>
</div>
<div class="card shadow-sm border-0">
<div class="card-body">
<div class="d-flex flex-wrap justify-content-between align-items-center gap-2 mb-3">
<div>
<h2 class="h5 card-title mb-1">Mints</h2>
<div id="mintResultSummary" class="small text-body-secondary">Aucune requête exécutée.</div>
<div class="small text-body-secondary">Source : <code>kb_sol_core_balance_changes.mint</code>.</div>
</div>
<div>
<div class="btn-group flex-wrap" role="group" aria-label="Actions mints">
<button id="useSelectedMintsButton" class="btn btn-sm btn-outline-secondary" type="button">Utiliser comme filtre transactions</button>
<button id="copyMintsButton" class="btn btn-sm btn-outline-primary" type="button">Copier valeurs multiligne</button>
<button id="exportMintsCsvButton" class="btn btn-sm btn-outline-success" type="button">Exporter CSV</button>
</div>
<div class="small text-body-secondary mt-1">Cochez une ligne. Sans sélection, laction accepte une seule ligne restant après le filtre local.</div>
</div>
</div>
<div class="table-responsive">
<table id="mintCandidateTable" class="table table-striped table-hover table-sm align-middle w-100">
<thead>
<tr>
<th class="replay-select-column"><span class="visually-hidden">Sélection</span></th>
<th>Mint</th>
<th data-bs-toggle="tooltip" title="Nombre de signatures distinctes dans lesquelles la valeur apparaît.">Transactions</th>
<th data-bs-toggle="tooltip" title="Nombre total de lignes core portant cette valeur.">Occurrences</th>
<th data-bs-toggle="tooltip" title="Occurrences divisées par le nombre de transactions distinctes.">Occ./tx</th>
<th data-bs-toggle="tooltip" title="Premier slot observé dans le corpus core.">Slot min</th>
<th data-bs-toggle="tooltip" title="Dernier slot observé dans le corpus core.">Slot max</th>
<th data-bs-toggle="tooltip" title="Différence entre le slot maximal et le slot minimal.">Étendue</th>
</tr>
</thead>
</table>
</div>
</div>
</div>
</section>
<section class="tab-pane fade" id="ownersTabPane" role="tabpanel" aria-labelledby="ownersTabButton" tabindex="0">
<div class="card shadow-sm border-0 mb-4">
<div class="card-body">
<div class="row g-3 align-items-end">
<div class="col-12 col-lg-7">
<label for="ownerContainsInput" class="form-label">Owner contient</label>
<input id="ownerContainsInput" class="form-control font-monospace" type="text" autocomplete="off" />
</div>
<div class="col-6 col-lg-2">
<label for="ownerLimitInput" class="form-label">Limite</label>
<input id="ownerLimitInput" class="form-control" type="number" min="1" max="5000" step="1" value="500" />
</div>
<div class="col-12 col-lg-3">
<div class="d-grid d-sm-flex gap-2">
<button id="resetOwnersButton" class="btn btn-outline-secondary" type="button">Réinitialiser</button>
<button id="loadOwnersButton" class="btn btn-primary flex-grow-1" type="button">Charger les owners</button>
</div>
</div>
</div>
</div>
</div>
<div class="card shadow-sm border-0">
<div class="card-body">
<div class="d-flex flex-wrap justify-content-between align-items-center gap-2 mb-3">
<div>
<h2 class="h5 card-title mb-1">Owners</h2>
<div id="ownerResultSummary" class="small text-body-secondary">Aucune requête exécutée.</div>
<div class="small text-body-secondary">Source : <code>kb_sol_core_balance_changes.owner</code>.</div>
</div>
<div>
<div class="btn-group flex-wrap" role="group" aria-label="Actions owners">
<button id="useSelectedOwnersButton" class="btn btn-sm btn-outline-secondary" type="button">Utiliser comme filtre transactions</button>
<button id="copyOwnersButton" class="btn btn-sm btn-outline-primary" type="button">Copier valeurs multiligne</button>
<button id="exportOwnersCsvButton" class="btn btn-sm btn-outline-success" type="button">Exporter CSV</button>
</div>
<div class="small text-body-secondary mt-1">Cochez une ligne. Sans sélection, laction accepte une seule ligne restant après le filtre local.</div>
</div>
</div>
<div class="table-responsive">
<table id="ownerCandidateTable" class="table table-striped table-hover table-sm align-middle w-100">
<thead>
<tr>
<th class="replay-select-column"><span class="visually-hidden">Sélection</span></th>
<th>Owner</th>
<th data-bs-toggle="tooltip" title="Nombre de signatures distinctes dans lesquelles la valeur apparaît.">Transactions</th>
<th data-bs-toggle="tooltip" title="Nombre total de lignes core portant cette valeur.">Occurrences</th>
<th data-bs-toggle="tooltip" title="Occurrences divisées par le nombre de transactions distinctes.">Occ./tx</th>
<th data-bs-toggle="tooltip" title="Premier slot observé dans le corpus core.">Slot min</th>
<th data-bs-toggle="tooltip" title="Dernier slot observé dans le corpus core.">Slot max</th>
<th data-bs-toggle="tooltip" title="Différence entre le slot maximal et le slot minimal.">Étendue</th>
</tr>
</thead>
</table>
</div>
</div>
</div>
</section>
<section class="tab-pane fade" id="accountsTabPane" role="tabpanel" aria-labelledby="accountsTabButton" tabindex="0">
<div class="card shadow-sm border-0 mb-4">
<div class="card-body">
<div class="row g-3 align-items-end">
<div class="col-12 col-lg-7">
<label for="accountContainsInput" class="form-label">Account key contient</label>
<input id="accountContainsInput" class="form-control font-monospace" type="text" autocomplete="off" />
</div>
<div class="col-6 col-lg-2">
<label for="accountLimitInput" class="form-label">Limite</label>
<input id="accountLimitInput" class="form-control" type="number" min="1" max="5000" step="1" value="500" />
</div>
<div class="col-12 col-lg-3">
<div class="d-grid d-sm-flex gap-2">
<button id="resetAccountsButton" class="btn btn-outline-secondary" type="button">Réinitialiser</button>
<button id="loadAccountsButton" class="btn btn-primary flex-grow-1" type="button">Charger les comptes</button>
</div>
</div>
</div>
</div>
</div>
<div class="card shadow-sm border-0">
<div class="card-body">
<div class="d-flex flex-wrap justify-content-between align-items-center gap-2 mb-3">
<div>
<h2 class="h5 card-title mb-1">Comptes</h2>
<div id="accountResultSummary" class="small text-body-secondary">Aucune requête exécutée.</div>
<div class="small text-body-secondary">Source : <code>kb_sol_core_account_keys.account_key</code>.</div>
</div>
<div>
<div class="btn-group flex-wrap" role="group" aria-label="Actions comptes">
<button id="useSelectedAccountsButton" class="btn btn-sm btn-outline-secondary" type="button">Utiliser comme filtre transactions</button>
<button id="copyAccountsButton" class="btn btn-sm btn-outline-primary" type="button">Copier valeurs multiligne</button>
<button id="exportAccountsCsvButton" class="btn btn-sm btn-outline-success" type="button">Exporter CSV</button>
</div>
<div class="small text-body-secondary mt-1">Cochez une ligne. Sans sélection, laction accepte une seule ligne restant après le filtre local.</div>
</div>
</div>
<div class="table-responsive">
<table id="accountCandidateTable" class="table table-striped table-hover table-sm align-middle w-100">
<thead>
<tr>
<th class="replay-select-column"><span class="visually-hidden">Sélection</span></th>
<th>Account key</th>
<th data-bs-toggle="tooltip" title="Nombre de signatures distinctes dans lesquelles la valeur apparaît.">Transactions</th>
<th data-bs-toggle="tooltip" title="Nombre total de lignes core portant cette valeur.">Occurrences</th>
<th data-bs-toggle="tooltip" title="Occurrences divisées par le nombre de transactions distinctes.">Occ./tx</th>
<th data-bs-toggle="tooltip" title="Premier slot observé dans le corpus core.">Slot min</th>
<th data-bs-toggle="tooltip" title="Dernier slot observé dans le corpus core.">Slot max</th>
<th data-bs-toggle="tooltip" title="Différence entre le slot maximal et le slot minimal.">Étendue</th>
</tr>
</thead>
</table>
</div>
</div>
</div>
</section>
</div>
</div>
</div>
</main>
<footer class="app-footer bg-dark text-light">
<div class="container h-100 d-flex align-items-center">
<div class="row flex-grow-1 align-items-center">
<div class="col-12 text-center text-small my-1 my-md-0">&copy; 2026 SASEDEV</div>
</div>
</div>
</footer>
<datalist id="knownProgramDatalist"></datalist>
<script type="module" src="ts/demo_sql_replay_candidates.ts" defer></script>
</body>
</html>