checkpoint ISAC registries and system monitoring

This commit is contained in:
JB
2026-07-27 00:31:16 -04:00
parent 8b80e55e6c
commit 7b3aff30d8
53 changed files with 1351 additions and 179 deletions
+22 -3
View File
@@ -5,7 +5,7 @@ import { requireDataView, requirePermission } from '$lib/server/auth/authorizati
import { getSessionUser } from '$lib/server/auth/session';
import { getDatabase } from '$lib/server/database';
import { recordIsacAudit } from '$lib/server/audit';
import { getPagination, getRegistrySearch } from '$lib/server/pagination';
import { getPagination, getRegistrySearch, getRegistrySort } from '$lib/server/pagination';
import { parseLoadoutDraft } from '$lib/builder/loadout';
const operators = new Set([
@@ -62,6 +62,24 @@ export const load: PageServerLoad = async ({ cookies, url }) => {
await requireDataView(await getSessionUser(cookies));
const database = await getDatabase();
const { search, pattern } = getRegistrySearch(url);
const observationCount = `((calibration.body_hit IS NOT NULL) + (calibration.critical_body_hit IS NOT NULL)
+ (calibration.headshot IS NOT NULL) + (calibration.critical_headshot IS NOT NULL)
+ (calibration.magazine_seconds IS NOT NULL) + (calibration.reload_seconds IS NOT NULL))`;
const sort = getRegistrySort(url, {
name: { asc: 'calibration.name COLLATE NOCASE ASC', desc: 'calibration.name COLLATE NOCASE DESC' },
weapon: { asc: 'calibration.selected_weapon ASC', desc: 'calibration.selected_weapon DESC' },
observations: {
asc: `${observationCount} ASC`,
desc: `${observationCount} DESC`,
defaultDirection: 'desc'
},
prediction: {
asc: '(calibration.predicted_json IS NOT NULL) ASC',
desc: '(calibration.predicted_json IS NOT NULL) DESC',
defaultDirection: 'desc'
},
state: { asc: 'calibration.status COLLATE NOCASE ASC', desc: 'calibration.status COLLATE NOCASE DESC' }
}, 'name');
const where = search ? "WHERE calibration.name LIKE ? ESCAPE '\\' COLLATE NOCASE" : '';
const args = search ? [pattern] : [];
const total = Number((await (await database.prepare(
@@ -77,7 +95,7 @@ export const load: PageServerLoad = async ({ cookies, url }) => {
FROM calculation_calibration_cases calibration
LEFT JOIN users user ON user.id=calibration.created_by
LEFT JOIN user_profiles profile ON profile.user_id=user.id
${where} ORDER BY calibration.updated_at DESC LIMIT ? OFFSET ?`
${where} ORDER BY ${sort.orderBy},calibration.name COLLATE NOCASE,calibration.id LIMIT ? OFFSET ?`
)).all(...args, pagination.perPage, pagination.offset),
(await database.prepare(`SELECT COUNT(*) AS total,
SUM(CASE WHEN status='ready' THEN 1 ELSE 0 END) AS ready,
@@ -95,7 +113,8 @@ export const load: PageServerLoad = async ({ cookies, url }) => {
calibrationCases,
calibrationSummary,
pagination,
search
search,
sort
};
};
+15 -2
View File
@@ -1,6 +1,8 @@
<script lang="ts">
import PendingForm from '$lib/components/PendingForm.svelte';
import RegistryInlineEditor from '$lib/components/RegistryInlineEditor.svelte';
import RegistryPagination from '$lib/components/RegistryPagination.svelte';
import SortableColumnHeader from '$lib/components/SortableColumnHeader.svelte';
import SearchableAssignment from '$lib/components/SearchableAssignment.svelte';
import SegmentedChoice from '$lib/components/SegmentedChoice.svelte';
import { createDraft } from '$lib/builder/loadout';
@@ -186,6 +188,7 @@
</div>
{/if}
{#snippet calibrationEditor()}
{#if calibrationEditing}
<div class="dashboard-editor calibration-editor">
<div class="editor-title"><div><p class="eyebrow">{calibrationEditing.id ? 'MODIFY CALIBRATION CASE' : 'NEW CALIBRATION CASE'}</p><h3>{calibrationEditing.name || 'FIELD OBSERVATION'}</h3></div><button aria-label="Close calibration editor" onclick={() => calibrationEditing = null}>×</button></div>
@@ -209,6 +212,11 @@
</PendingForm>
</div>
{/if}
{/snippet}
{#if calibrationEditing && !calibrationEditing.id}
{@render calibrationEditor()}
{/if}
<div class="calculation-revision-registry">
<div class="selection-head"><div><span>CALCULATION REVISIONS</span><small>SAVED BUILDS USE THE ACTIVE REVISION</small></div><PendingForm action="?/suggestRevision">{#snippet children(pending)}<button class="secondary" disabled={pending}>{pending ? 'ANALYZING…' : 'GENERATE ASSISTED SUGGESTION'}</button>{/snippet}</PendingForm></div>
@@ -232,9 +240,14 @@
<div class="selection-head"><div><span>CALIBRATION REGISTRY</span><small>OBSERVED GAME VALUES + MODEL COMPARISON</small></div><b>{Number(data.calibrationSummary?.total ?? 0)} CASES</b></div>
<RegistryPagination pagination={data.pagination} search={data.search}/>
<div class="dashboard-table">
<div class="dashboard-row calibration-row table-heading"><span>CASE</span><span>WEAPON</span><span>OBSERVATIONS</span><span>PREDICTION</span><span>STATE</span><span></span></div>
<div class="dashboard-row calibration-row table-heading"><SortableColumnHeader label="CASE" column="name" sort={data.sort}/><SortableColumnHeader label="WEAPON" column="weapon" sort={data.sort}/><SortableColumnHeader label="OBSERVATIONS" column="observations" sort={data.sort} defaultDirection="desc"/><SortableColumnHeader label="PREDICTION" column="prediction" sort={data.sort} defaultDirection="desc"/><SortableColumnHeader label="STATE" column="state" sort={data.sort}/><span></span></div>
{#each data.calibrationCases as item}
<div class="dashboard-row calibration-row"><div><strong>{item.name}</strong><small>{item.game_version || 'GAME VERSION NOT RECORDED'} · {item.creator_name}</small></div><span>{Number(item.selected_weapon) === 0 ? 'PRIMARY' : 'SECONDARY'}</span><span>{[item.body_hit,item.critical_body_hit,item.headshot,item.critical_headshot,item.magazine_seconds,item.reload_seconds].filter((value) => value !== null).length} / 6 CORE</span><span>{item.predicted_json ? 'AVAILABLE' : 'INSUFFICIENT DATA'}</span><b class:configured={item.status === 'ready'} class="state-dot">{item.status.toUpperCase()}</b><button onclick={() => calibrationEditing = calibrationFrom(item)}>EDIT →</button></div>
<div class="dashboard-row calibration-row" class:registry-row-editing={String(calibrationEditing?.id ?? '') === String(item.id)}><div><strong>{item.name}</strong><small>{item.game_version || 'GAME VERSION NOT RECORDED'} · {item.creator_name}</small></div><span>{Number(item.selected_weapon) === 0 ? 'PRIMARY' : 'SECONDARY'}</span><span>{[item.body_hit,item.critical_body_hit,item.headshot,item.critical_headshot,item.magazine_seconds,item.reload_seconds].filter((value) => value !== null).length} / 6 CORE</span><span>{item.predicted_json ? 'AVAILABLE' : 'INSUFFICIENT DATA'}</span><b class:configured={item.status === 'ready'} class="state-dot">{item.status.toUpperCase()}</b><button aria-expanded={String(calibrationEditing?.id ?? '') === String(item.id)} aria-controls={`calibration-editor-${item.id}`} onclick={() => calibrationEditing = calibrationFrom(item)}>EDIT →</button></div>
{#if String(calibrationEditing?.id ?? '') === String(item.id)}
<RegistryInlineEditor id={`calibration-editor-${item.id}`} label={`Edit ${item.name}`}>
{@render calibrationEditor()}
</RegistryInlineEditor>
{/if}
{/each}
</div>