test(okr): utvid syklus-fixture med KR-frontmatter og begge OKR-typene
This commit is contained in:
parent
e3a99b02ff
commit
e767922154
3 changed files with 109 additions and 0 deletions
|
|
@ -6,7 +6,25 @@ description: Tertialmaal for digital selvbetjening.
|
|||
tags:
|
||||
- digital
|
||||
timestamp: '2026-02-01T09:05:00+00:00'
|
||||
kr1_navn: Andel digitale soeknader (prosent)
|
||||
kr1_baseline: 60
|
||||
kr1_target: 85
|
||||
kr1_naa: 63
|
||||
kr1_type: aspirational
|
||||
kr2_navn: Gjennomsnittlig saksbehandlingstid (dager)
|
||||
kr2_baseline: 14
|
||||
kr2_target: 5
|
||||
kr2_naa: 11
|
||||
kr2_type: aspirational
|
||||
---
|
||||
# Digitalisering av tjenester
|
||||
|
||||
Objective: Oeke selvbetjeningsgrad i publikumstjenester.
|
||||
KR1: Oeke andel digitale soeknader fra 60 til 85 prosent.
|
||||
- Maalemetode: Andel soeknader levert via selvbetjeningsloesningen.
|
||||
- Datakilde: Soeknadsloggen.
|
||||
- Type: Aspirational
|
||||
KR2: Redusere gjennomsnittlig saksbehandlingstid fra 14 til 5 dager.
|
||||
- Maalemetode: Median tid fra mottak til vedtak.
|
||||
- Datakilde: Saksbehandlingssystemet.
|
||||
- Type: Aspirational
|
||||
|
|
|
|||
|
|
@ -7,8 +7,25 @@ tags:
|
|||
- sikkerhet
|
||||
- tunnel
|
||||
timestamp: '2026-02-01T09:00:00+00:00'
|
||||
kr1_navn: Alvorlige tunnelhendelser (antall)
|
||||
kr1_baseline: 0
|
||||
kr1_target: 0
|
||||
kr1_naa: 0
|
||||
kr1_type: committed
|
||||
kr2_navn: Tunneler med oppgradert sikkerhetsutrustning (antall)
|
||||
kr2_baseline: 12
|
||||
kr2_target: 20
|
||||
kr2_naa: 17
|
||||
kr2_type: committed
|
||||
---
|
||||
# Trafikksikkerhet og tunnelsikkerhet
|
||||
|
||||
Objective: Styrke tunnelsikkerhet i tertialet.
|
||||
KR1: Naa nullvisjon for alvorlige tunnelhendelser.
|
||||
- Maalemetode: Registrerte alvorlige hendelser i hendelsesdatabasen.
|
||||
- Datakilde: Vegtrafikksentralen.
|
||||
- Type: Committed
|
||||
KR2: Oeke antall tunneler med oppgradert sikkerhetsutrustning fra 12 til 20.
|
||||
- Maalemetode: Telling av ferdigattesterte tunneler.
|
||||
- Datakilde: Prosjektportefoeljen.
|
||||
- Type: Committed
|
||||
|
|
|
|||
74
tests/syklus-data.test.mjs
Normal file
74
tests/syklus-data.test.mjs
Normal file
|
|
@ -0,0 +1,74 @@
|
|||
// syklus-data.test.mjs
|
||||
// D5 (fase D, steg 7-8): datamodellen for styringssloeyfa. Testene deles i to lag
|
||||
// som landet i hver sin commit:
|
||||
// (A) FIXTURE-KONTRAKTEN (steg 7) -- asserterer paa fixture-INNHOLD, ikke paa
|
||||
// lib-kode. Disse er roede foer fixturen utvides og groenne etterpaa, slik at
|
||||
// steg 8 har data aa bygge mot (RED-baseline-disiplin, jf. innboks-ingest).
|
||||
// (B) LESER + SCOREBEREGNING (steg 8) -- lib/syklus-data.mjs.
|
||||
//
|
||||
// Beslutning B-1: flate `krN_`-noekler i okr-*.md sin frontmatter. Verifisert kjoert,
|
||||
// ikke bare lest: `^\s*type:` i lib/frontmatter.mjs:29 matcher ikke `kr1_type:`, saa
|
||||
// OKF-noekkelen `type` og KR-noekkelen `krN_type` kolliderer ikke.
|
||||
// Beslutning B-2: score BEREGNES, lagres aldri. target == baseline gir undefined.
|
||||
//
|
||||
// Offline, zero-dep, node:test. Test-kilden holdes ASCII-ren (bash 3.2 set -u).
|
||||
|
||||
import { test } from 'node:test';
|
||||
import assert from 'node:assert/strict';
|
||||
import { readFileSync } from 'node:fs';
|
||||
import { join, dirname } from 'node:path';
|
||||
import { fileURLToPath } from 'node:url';
|
||||
|
||||
const ROOT = join(dirname(fileURLToPath(import.meta.url)), '..');
|
||||
const SYKLUS = 'tests/fixtures/okf-realistic/syklus/T1-2026';
|
||||
const OKR_FILER = ['okr-trafikksikkerhet.md', 'okr-digitalisering.md'];
|
||||
|
||||
const lesFixture = (navn) => readFileSync(join(ROOT, SYKLUS, navn), 'utf8');
|
||||
|
||||
// --- (A) Fixture-kontrakten (steg 7) ---
|
||||
|
||||
test('(A1) steg 7: begge OKR-fixturene baerer kr1_baseline', () => {
|
||||
const missing = OKR_FILER.filter((f) => !/^\s*kr1_baseline\s*:/m.test(lesFixture(f)));
|
||||
assert.deepEqual(
|
||||
missing,
|
||||
[],
|
||||
`fixture-OKR uten kr1_baseline: ${missing.join(', ')}`,
|
||||
);
|
||||
});
|
||||
|
||||
test('(A2) steg 7: begge KR-typene forekommer i fixturen', () => {
|
||||
const alle = OKR_FILER.map(lesFixture).join('\n');
|
||||
assert.match(alle, /^\s*kr\d+_type\s*:\s*committed\s*$/m, 'ingen committed KR i fixturen');
|
||||
assert.match(
|
||||
alle,
|
||||
/^\s*kr\d+_type\s*:\s*aspirational\s*$/m,
|
||||
'ingen aspirational KR i fixturen',
|
||||
);
|
||||
});
|
||||
|
||||
// B-2-kanten skal vaere dekket av DATA, ikke bare av enhetstest -- ellers moeter
|
||||
// generatoren i steg 9-10 den foerste gang i produksjon.
|
||||
test('(A3) steg 7: fixturen inneholder ett KR-par der target == baseline', () => {
|
||||
const funn = [];
|
||||
for (const f of OKR_FILER) {
|
||||
const doc = lesFixture(f);
|
||||
for (const m of doc.matchAll(/^\s*kr(\d+)_baseline\s*:\s*(\S+)\s*$/gm)) {
|
||||
const t = new RegExp(`^\\s*kr${m[1]}_target\\s*:\\s*(\\S+)\\s*$`, 'm').exec(doc);
|
||||
if (t && t[1] === m[2]) funn.push(`${f}:kr${m[1]}`);
|
||||
}
|
||||
}
|
||||
assert.ok(
|
||||
funn.length >= 1,
|
||||
'ingen KR med target == baseline -- udefinert-score-kanten (B-2) er udekket av data',
|
||||
);
|
||||
});
|
||||
|
||||
// OKF-laget skal vaere uroert av KR-utvidelsen: `type:` er fortsatt OKR-typen, ikke
|
||||
// en KR-type. Dette er antakelse 2 i planen, her bundet til faktisk fixture-innhold.
|
||||
test('(A4) steg 7: krN_type forstyrrer ikke OKF-noekkelen type', async () => {
|
||||
const { parseFrontmatter } = await import('../lib/frontmatter.mjs');
|
||||
for (const f of OKR_FILER) {
|
||||
const fm = parseFrontmatter(lesFixture(f));
|
||||
assert.equal(fm.get('type'), 'OKR', `${f}: OKF-type forskjovet av krN_type`);
|
||||
}
|
||||
});
|
||||
Loading…
Add table
Add a link
Reference in a new issue