Versie 0.2.0

This commit is contained in:
Atreides Assets committed 2026-10-29 11:57:29 +01:00
commit e77d8fd373
495 files changed
+81026

No files matched your search

+145
View File
@@ -0,0 +1,145 @@
// Generated, do not edit. sha256:85fb028950f59216bdb01fd8cdbb5cd92ec098e018550fd5116c6e26d75ba680
import { describe, it, before } from 'node:test';
import assert from 'node:assert/strict';
import { FIELD_POLICY, TABLE_POLICY, fieldClass, strictestClass } from '../../server/ai/policy.js';
import { openBaselineDb } from '../helpers/baseline-db.mjs';
import { CONFIG } from '../../shared/config.js';
let KOLOMMEN;
before(() => {
const db = openBaselineDb();
const tabellen = db.prepare(
`SELECT name FROM sqlite_master WHERE type = 'table' AND name NOT LIKE 'sqlite_%'`
).all().map(r => r.name);
KOLOMMEN = new Set();
for (const t of tabellen) {
for (const k of db.prepare(`PRAGMA table_info(${t})`).all()) KOLOMMEN.add(k.name);
}
});
describe('AI-veldbeleid tegen het schema', () => {
it('classificeert élke kolom uit de baseline', () => {
const zonder = [...KOLOMMEN].filter(k => fieldClass(k) === null).sort();
assert.deepEqual(zonder, [],
`deze kolommen hebben geen klasse in server/ai/policy.js: ${zonder.join(', ')}`);
});
const GEEN_KOLOM = new Set(['portfolio', 'fiatValue']);
it('bevat geen regel voor een kolom die niet bestaat', () => {
const spoken = Object.keys(FIELD_POLICY).filter(k => !KOLOMMEN.has(k) && !GEEN_KOLOM.has(k)).sort();
assert.deepEqual(spoken, [],
`deze regels wijzen naar een kolom die niet (meer) bestaat: ${spoken.join(', ')}`);
});
it('houdt de uitzonderingenlijst eerlijk: elk veld erin is ook echt geen kolom', () => {
const tochKolom = [...GEEN_KOLOM].filter(k => KOLOMMEN.has(k)).sort();
assert.deepEqual(tochKolom, [],
`deze staan als uitzondering maar zijn wél een kolom: ${tochKolom.join(', ')}`);
});
it('gebruikt alleen klassen die in CONFIG.AI.FIELD_CLASSES staan', () => {
const onbekend = [...new Set(Object.values(FIELD_POLICY))]
.filter(k => !CONFIG.AI.FIELD_CLASSES.includes(k)).sort();
assert.deepEqual(onbekend, []);
});
});
describe('AI-veldbeleid: de gevaarlijke velden', () => {
const KETEN = ['address', 'externalAddress', 'automaticLabel', 'txid', 'transactionHash',
'blockHeight', 'blockTime', 'chainIndex', 'derivationIndex', 'scriptType'];
const WEG = ['value', 'rawData', 'settings', 'arguments'];
for (const veld of KETEN) {
it(`${veld} is keten-data en gaat alleen als alias`, () => {
assert.equal(fieldClass(veld), 'chain');
});
}
for (const veld of WEG) {
it(`${veld} verlaat de machine in geen enkele vorm`, () => {
assert.equal(fieldClass(veld), 'drop');
});
}
it('laat geen enkele hoeveelheid als plain door', () => {
for (const veld of ['amount', 'balance', 'balanceSats', 'valueSats', 'feeSats',
'balanceFound', 'unitFee', 'principalAmount']) {
assert.equal(fieldClass(veld), 'quantity', `${veld} hoort in de klasse quantity`);
}
});
it('kent geen enkel veld dat ongedeclareerd tóch een waarde geeft', () => {
assert.equal(fieldClass('eenNieuweKolomDieNietBestaat'), null);
assert.equal(fieldClass('constructor'), null);
assert.equal(fieldClass('toString'), null);
});
});
describe('AI-veldbeleid: de uitzonderingen per tabel', () => {
it('geeft zonder tabel-argument nog steeds de gevoeligste lezing', () => {
assert.equal(fieldClass('value'), 'drop');
assert.equal(fieldClass('value', null), 'drop');
assert.equal(fieldClass('value', 'WalletSource'), 'drop');
assert.equal(fieldClass('value', 'EenTabelDieNietBestaat'), 'drop');
});
it('past de uitzondering toe voor precies de tabel die hem heeft', () => {
assert.equal(fieldClass('value', 'Preference'), 'plain');
assert.equal(fieldClass('Preference.value'), 'plain');
assert.equal(fieldClass('WalletSource.value'), 'drop');
});
it('kan met een uitzondering geen veld OPENZETTEN dat de basis niet kent', () => {
assert.equal(fieldClass('eenVeldDatNergensStaat', 'Preference'), null);
assert.equal(fieldClass('Preference.eenVeldDatNergensStaat'), null);
assert.equal(fieldClass('constructor', 'Preference'), null);
});
it('noemt in elke uitzondering een tabel en een veld die echt bestaan', () => {
const tabellen = new Set();
const db = openBaselineDb();
for (const r of db.prepare(
`SELECT name FROM sqlite_master WHERE type = 'table' AND name NOT LIKE 'sqlite_%'`).all()) {
tabellen.add(r.name);
}
for (const [tabel, velden] of Object.entries(TABLE_POLICY)) {
assert.ok(tabellen.has(tabel), `TABLE_POLICY noemt tabel '${tabel}', die niet bestaat`);
const kolommen = new Set(db.prepare(`PRAGMA table_info(${tabel})`).all().map(k => k.name));
for (const [veld, klasse] of Object.entries(velden)) {
assert.ok(kolommen.has(veld), `${tabel}.${veld} is geen kolom van die tabel`);
assert.ok(CONFIG.AI.FIELD_CLASSES.includes(klasse), `${tabel}.${veld} heeft een onbekende klasse`);
assert.ok(Object.hasOwn(FIELD_POLICY, veld),
`${tabel}.${veld} staat niet in het basisbeleid, dus de uitzondering doet niets`);
}
}
});
it('houdt de lijst kort, want elke regel is een plek waar de gevoeligste lezing NIET geldt', () => {
const regels = Object.values(TABLE_POLICY).reduce((n, v) => n + Object.keys(v).length, 0);
assert.ok(regels <= 5, `${regels} uitzonderingen; een uitzondering is een veld dat de AI onbewerkt ziet, dus niet zomaar meer`);
});
});
describe('strictestClass', () => {
it('kiest de gevoeligste van twee', () => {
assert.equal(strictestClass('plain', 'chain'), 'chain');
assert.equal(strictestClass('chain', 'plain'), 'chain');
assert.equal(strictestClass('handle', 'drop'), 'drop');
assert.equal(strictestClass('quantity', 'quantityFiat'), 'quantity');
});
it('behandelt een ontbrekende klasse als "de andere"', () => {
assert.equal(strictestClass(null, 'plain'), 'plain');
assert.equal(strictestClass('plain', null), 'plain');
});
it('is de regel waarmee de botsende namen zijn ingedeeld', () => {
assert.equal(fieldClass('value'), 'drop');
assert.equal(fieldClass('name'), 'handle');
assert.equal(fieldClass('key'), 'plain');
});
});