Improve operational UX, recovery flows, and action safety

Implement the approved UX review across Fleet, Betas, Library, deployments, and Settings. Add reviewed promotion and reconciliation plans, atomic queued-removal cancellation, recoverable beta drafts and launch inputs, accessible controls, and mobile improvements.

Validated with 473 tests, a clean typecheck, production build, and isolated desktop/mobile browser walkthroughs. Include the review and implementation coverage notes.
This commit is contained in:
2026-09-19 21:34:34 -04:00
parent 940f81e6ca
commit 8ac420fe61
83 changed files with 2574 additions and 1190 deletions
+35
View File
@@ -0,0 +1,35 @@
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
import { newFixture, type Fixture } from '../helpers/fixture.js';
let fixture: Fixture;
const server = 't5_zombie_theater_1';
beforeEach(async () => {
vi.resetModules(); fixture = await newFixture([server]);
const { seedServerRegistry } = await import('../../src/lib/server/fleet/servers.js');
await seedServerRegistry();
});
afterEach(async () => { await fixture.cleanup(); });
describe('scope impact preview', () => {
it('reports unscoping tracked script copies without changing scope or inventory', async () => {
const { createScript, getScript } = await import('../../src/lib/server/fleet/scripts.js');
const { recordScript, listServerScripts } = await import('../../src/lib/server/fleet/inventory.js');
const { GET } = await import('../../src/routes/api/scripts/[id]/scope/+server.js');
const script = createScript({ name: 'Example', scopeType: 'game', scopeValue: 't5', targetRelPath: 'example.gsc', content: Buffer.from('example') });
recordScript(server, 'example.gsc', script.version.id, script.version.sha256, script.version.size, 'test');
const response = await GET({ params: { id: String(script.script.id) }, url: new URL('http://localhost/?type=none') });
expect(await response.json()).toMatchObject({ before: [server], after: [], removed: [server], detached: [server], affected: [server], composed: false });
expect(getScript(script.script.id)?.scope_type).toBe('game');
expect(listServerScripts(server)).toHaveLength(1);
});
it('reports config composition impact separately from detached inventory', async () => {
const { createScript } = await import('../../src/lib/server/fleet/scripts.js');
const { GET } = await import('../../src/routes/api/scripts/[id]/scope/+server.js');
const config = createScript({ name: 'Overlay', kind: 'config', scopeType: 'game', scopeValue: 't5', content: Buffer.from('set g_inactivity 0') });
const response = await GET({ params: { id: String(config.script.id) }, url: new URL('http://localhost/?type=none') });
expect(await response.json()).toMatchObject({ composed: true, detached: [], affected: [server], removed: [server] });
const invalid = await GET({ params: { id: String(config.script.id) }, url: new URL('http://localhost/?type=invalid&value=t5') });
expect(invalid.status).toBe(400);
});
});