feat: add isolated release gates and CI checks

This commit is contained in:
jb
2026-09-19 10:01:23 -04:00
parent 0ff3e67568
commit 92272d4e9a
20 changed files with 442 additions and 10 deletions
+14 -2
View File
@@ -7,6 +7,7 @@ import { TokenCipher, hashSecret } from './security';
import { EveSso, type VerifiedGrant } from './sso';
import { EsiClient, EsiMarketEstimates } from './esi';
import { SqliteReferenceRepository } from './reference';
import { capabilityDisabledReason, capabilityEnabled, type ReleaseCapability } from './release-gate';
export const SESSION_COOKIE = 'eve_session';
export type Session = { userId: string; sessionId: string };
@@ -51,7 +52,14 @@ export async function charactersFor(userId: string | null): Promise<Character[]>
return userId ? repository().characters(userId) : [];
}
/** Both conventional browsing and the assistant enter here. A request pins one reference artifact. */
export async function assetReport(userId: string | null) {
export async function assetReport(
userId: string | null,
capability: Extract<ReleaseCapability, 'asset_search' | 'asset_valuation'> = 'asset_valuation',
) {
const config = configuration();
if (!capabilityEnabled(capability, config.capabilityAllowlist)) {
return { status: 'unavailable' as const, reason: capabilityDisabledReason(capability) };
}
let reference: SqliteReferenceRepository | undefined;
const getReference = () => {
const config = configuration();
@@ -91,7 +99,11 @@ async function characterGrant(userId: string, characterId: number, revalidateOwn
try { return await promise; } finally { if (refreshes.get(key) === promise) refreshes.delete(key); }
}
export async function synchronize(userId: string) {
if (configuration().mode === 'demo') return { completed: 2, failed: [] as number[], demo: true };
const config = configuration();
if (!capabilityEnabled('asset_sync', config.capabilityAllowlist)) {
throw new Error(capabilityDisabledReason('asset_sync'));
}
if (config.mode === 'demo') return { completed: 2, failed: [] as number[], demo: true };
const { store, esi } = live();
const characters = await store.characters(userId);
const failed: number[] = []; let completed = 0;