Sesjon 3 av 3 — leverer Fase 7-9 av v1.11.0-planen. Fase 7 (Acme-rename på demo-state): - Rename "Acme AS" → "Acme Kommune" og "Demosystem" → "Acme Kunde-chatbot" konsistent på tvers av alle 17 fixtures. - build-demo-state.mjs: organization.name → "Acme Kommune", projects[0] → id "acme-kunde-chatbot" / name "Acme: Kunde-chatbot". - Re-bygd demo-state-v1-blokk i playground HTML. Fase 8 (Screenshots-regenerering): - 24 nye PNG-er under playground/screenshots/v1.11.0/ (12 surfaces × 2 tema, retina, fullPage). v1.10.0-mappen beholdt som historisk referanse. - tests/screenshot/run.mjs: OUT_DIR + kommentarer bumpet til v1.11.0. Fase 9 (Release: docs + versjonsbump): - plugin.json 1.10.1 → 1.11.0. - README.md (plugin): version-badge + Version History + screenshot-gallery refs + demo-data refs oppdatert. - CLAUDE.md (plugin): Playground-overskrift v3/v1.10.0 → v3/v1.11.0, Demo system-seksjon v1.10.1 → v1.11.0, screenshot-refs v1.10.0 → v1.11.0, "Inline CSS-kandidater" konvertert til "Design-system 100%-adoption" status. - Root README.md: ms-ai-architect-versjon 1.10.1 → 1.11.0, demo-tekst og Playground-tekst regenerert for v1.11.0, "271 PASS combined" → "278 PASS". Verifisering: - bash tests/run-e2e.sh --playground → 271/271 PASS (static + parsers). - bash tests/test-playground-migrations.sh → 7/7 PASS. - Total: 278/278 PASS, 0 FAIL. Refs: NEXT-SESSION-PROMPT.local.md (Sesjon 3 av 3, plan .claude/plans/jeg-skal-pr-ve-effervescent-token.md). Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
141 lines
6.2 KiB
JavaScript
141 lines
6.2 KiB
JavaScript
#!/usr/bin/env node
|
|
// Build demo state for playground v3.
|
|
//
|
|
// Reads all fixtures from playground/test-fixtures/*.md and inlines them as a
|
|
// <script type="application/json" id="demo-state-v1"> block in the playground
|
|
// HTML. The "Last inn demo-data" button on the onboarding surface reads this
|
|
// block and bootstraps a complete demo: filled organization, one demo project,
|
|
// all 17 reports pre-imported as raw_markdown.
|
|
//
|
|
// Idempotent: detects existing block by id and replaces it; otherwise injects
|
|
// after </main>. Run from plugin root (or anywhere — uses script-relative paths).
|
|
//
|
|
// Usage: node scripts/build-demo-state.mjs
|
|
|
|
import { readFileSync, writeFileSync, readdirSync } from 'node:fs';
|
|
import { join, dirname, resolve } from 'node:path';
|
|
import { fileURLToPath } from 'node:url';
|
|
|
|
const __filename = fileURLToPath(import.meta.url);
|
|
const __dirname = dirname(__filename);
|
|
const PLUGIN_ROOT = resolve(__dirname, '..');
|
|
const PLAYGROUND_HTML = join(PLUGIN_ROOT, 'playground', 'ms-ai-architect-playground.html');
|
|
const FIXTURES_DIR = join(PLUGIN_ROOT, 'playground', 'test-fixtures');
|
|
|
|
// 17 commands that produce reports (must match CATALOG.commands order in playground).
|
|
const REPORT_COMMANDS = [
|
|
'classify', 'requirements', 'transparency', 'frimpact', 'conformity', 'dpia',
|
|
'security', 'ros', 'review',
|
|
'cost', 'license',
|
|
'migrate', 'adr', 'summary', 'poc', 'utredning', 'compare'
|
|
];
|
|
|
|
function readFixture(cmdId) {
|
|
const path = join(FIXTURES_DIR, cmdId + '.md');
|
|
try {
|
|
return readFileSync(path, 'utf8');
|
|
} catch (e) {
|
|
console.warn('[build-demo-state] skipped fixture (missing): ' + cmdId);
|
|
return null;
|
|
}
|
|
}
|
|
|
|
function buildDemoState() {
|
|
const reports = {};
|
|
let count = 0;
|
|
REPORT_COMMANDS.forEach(function (cmdId) {
|
|
const md = readFixture(cmdId);
|
|
if (md == null) return;
|
|
reports[cmdId] = { input: {}, raw_markdown: md };
|
|
count++;
|
|
});
|
|
console.log('[build-demo-state] inlined ' + count + ' fixtures of ' + REPORT_COMMANDS.length);
|
|
|
|
return {
|
|
schemaVersion: 1,
|
|
dataVersion: 2,
|
|
shared: {
|
|
organization: {
|
|
name: 'Acme Kommune',
|
|
description: 'Mellomstor norsk kommune med ~8 000 ansatte. Ansvar for skole, helse, byggesak og digitalisering. Bruker pluginen for å vurdere AI-tjenester før innføring.',
|
|
sector: 'Kommunal',
|
|
size: '8 000'
|
|
},
|
|
regulatory: {
|
|
regulatory_requirements: 'GDPR/Personopplysningsloven, Sikkerhetsloven, Forvaltningsloven, Arkivloven, Helseregisterloven (for helsetjenestene)',
|
|
ai_act_role: 'deployer',
|
|
risk_level: 'high'
|
|
},
|
|
technology: {
|
|
cloud_platform: 'Azure (Norge Øst), M365 E5, on-prem datasenter for kommunale fagsystem',
|
|
license_type: 'M365 E5 (alle ansatte) + Azure Enterprise Agreement + Power Platform per app',
|
|
ai_services_in_use: 'Azure OpenAI (GPT-4o), Azure AI Search, Copilot for M365 (pilot 50 brukere), Power Automate AI Builder'
|
|
},
|
|
security: {
|
|
data_classification: ['Åpen', 'Intern', 'Fortrolig'],
|
|
data_residency: 'EU/EØS — fortrinnsvis Norge',
|
|
dpia_practice: 'Sentralt personvernombud + kommune-DPO. Mal etter Datatilsynet. DPIA er obligatorisk for alle nye AI-tjenester som behandler personopplysninger.',
|
|
certifications: 'ISO 27001, NSM grunnprinsipper for IKT-sikkerhet, Digdir Trygg-pilot'
|
|
},
|
|
architecture: {
|
|
preferred_platform: 'Azure AI Foundry (for nye løsninger), Copilot Studio (for low-code agenter)',
|
|
integration_needs: 'M365, Public 360 (sak/arkiv), KOMTEK (byggesak), Visma Enterprise HRM, REST API mot folkeregister og matrikkel',
|
|
annual_ai_budget: '3 MNOK (2026), forventet 5 MNOK (2027)'
|
|
},
|
|
business: {
|
|
governance_model: 'Sentralt AI-råd ledes av digitaliseringsdirektør. Beslutninger over 500 kNOK eskalerer til CIO. Tillitsvalgt og personvernombud inkluderes i alle høyrisiko-vurderinger.',
|
|
doc_format_preferences: 'Markdown for tekniske dokumenter, PDF for styringsdokumenter, Confluence for arbeidsdokumenter',
|
|
reference_architecture: 'TOGAF-tilpasset, Digdir arkitekturprinsipper, intern Confluence /arkitektur'
|
|
}
|
|
},
|
|
projects: [
|
|
{
|
|
id: 'acme-kunde-chatbot',
|
|
name: 'Acme: Kunde-chatbot',
|
|
description: 'AI-chatbot som hjelper innbyggere med byggesak-spørsmål. Trenger DPIA, ROS, EU AI Act-klassifisering og kostnadsestimat før beslutning. Alle 17 rapport-typer er pre-importert med eksempel-data.',
|
|
scenarios: ['Chatbot/agent', 'Beslutningsstøtte'],
|
|
createdAt: '2026-05-04T08:00:00.000Z',
|
|
reports: reports
|
|
}
|
|
],
|
|
activeProjectId: 'acme-kunde-chatbot',
|
|
activeSurface: 'project',
|
|
preferences: { theme: 'dark' }
|
|
};
|
|
}
|
|
|
|
function injectIntoHtml(html, jsonString) {
|
|
const blockOpen = '<script type="application/json" id="demo-state-v1">';
|
|
const blockClose = '</script>';
|
|
const fullBlock = ' ' + blockOpen + '\n' + jsonString + '\n ' + blockClose;
|
|
|
|
// Detect existing block (idempotent replace).
|
|
const re = /[ \t]*<script type="application\/json" id="demo-state-v1">[\s\S]*?<\/script>/;
|
|
if (re.test(html)) {
|
|
return html.replace(re, fullBlock);
|
|
}
|
|
// Inject after </main>.
|
|
const mainClose = '</main>';
|
|
const idx = html.indexOf(mainClose);
|
|
if (idx === -1) {
|
|
throw new Error('[build-demo-state] could not find </main> in playground HTML');
|
|
}
|
|
const insertAt = idx + mainClose.length;
|
|
return html.slice(0, insertAt) + '\n\n <!-- Inlined demo-state for "Last inn demo-data"-knapp. Bygges av\n scripts/build-demo-state.mjs fra playground/test-fixtures/*.md.\n IKKE rediger manuelt — kjør skriptet på nytt. -->\n' + fullBlock + html.slice(insertAt);
|
|
}
|
|
|
|
function main() {
|
|
const state = buildDemoState();
|
|
const json = JSON.stringify(state, null, 2);
|
|
const html = readFileSync(PLAYGROUND_HTML, 'utf8');
|
|
const out = injectIntoHtml(html, json);
|
|
if (out === html) {
|
|
console.log('[build-demo-state] no change (already up-to-date)');
|
|
return;
|
|
}
|
|
writeFileSync(PLAYGROUND_HTML, out, 'utf8');
|
|
console.log('[build-demo-state] wrote demo-state-v1 block to ' + PLAYGROUND_HTML);
|
|
console.log('[build-demo-state] block size: ' + (json.length / 1024).toFixed(1) + ' KB');
|
|
}
|
|
|
|
main();
|