feat(openkat): het echte exportformaat, als Uitbreiding met een vaste rapportagemap #789

Merged
brenno merged 5 commits from feat/openkat-uitbreiding-integraties into main 2026-07-24 09:18:08 +00:00
Owner

Sluit het gat tussen wat de OpenKAT-import beloofde en wat hij deed, en zet hem op de plek waar hij hoort.

De import las het verkeerde formaat

De importlaag was geschreven zonder een echte export bij de hand: hij zocht systems en findings náást elkaar op het hoogste niveau. Zo ziet geen enkele OpenKAT-export eruit. Getoetst tegen zes echte exports kwam er een leeg deck uit — de bestanden werden wél "herkend", maar leverden nul systemen en nul bevindingen.

Elke export heeft één envelop ({organization_code, organization_name, organization_tags, data}); het verschil zit in data: een vlakke samenvatting van de hele organisatie, of gesleuteld op rapporttype en daarbinnen op object. Beide worden nu gelezen. Wat daarbij aan het licht kwam:

  • Bevindingen zitten in de deelrapporten, niet in findings-report — die is in echte exports leeg. Vier van de zes bestanden hadden anders nul bevindingen opgeleverd terwijl er 284 in zaten.
  • De noemer ging verloren, waardoor OpenKatControlScore.ratio per definitie null was en de aggregator geen trend kón berekenen.
  • Herimport was niet reproduceerbaar: het organisatierapport draagt zelf geen datum en viel terug op DateTime.now(). De trendlijn werd zo een grafiek van het aantal keren dat je op Importeren drukte.
  • De datumstempel van de exportknop werd niet gelezen (<organisatie>_20260319200604.json — veertien cijfers zonder scheidingstekens).
  • name is geregeld null in echte exports; dat gaf "null" op de dia.

En de plek waar het hoort

Vierde optionele module, standaard uit, plus een nieuw tabblad Integraties met de rapportagemap. De import gebruikt die map rechtstreeks in plaats van er elke keer om te vragen. Reveal = module aan óf map aangewezen, zodat uitzetten een bestaand OpenKAT-deck niet onbijwerkbaar maakt.

Verantwoording

  • Getoetst tegen zes echte exports: 6 van 6 herkend, 15 dia's met echte inhoud. Die bestanden staan niet in de repo — het zijn scangegevens van echte organisaties; de fixtures dragen de vorm met verzonnen namen.
  • Twee klasseplafonds tripten; beide opgelost door er gedrag uit te halen, niet door de basislijn te verhogen. Het Integraties-paneel is daarom een losse widget geworden in plaats van een part — de scheiding die #631 voor deze dialoog wilde.
  • De zoektoets kende alleen _xxx()-bouwers als tabbladinhoud; een tabblad dat door een losse widget wordt gerenderd viel stil buiten de telling. Nu herkent hij beide vormen.
  • 10 nieuwe strings x 31 talen; "OpenKAT" als leenwoord.
  • make check groen: 6196 toetsen, dekking 86,4%.

Openstaand

Deze PR bouwt op het formaat van de exports die nu voorhanden zijn (maart en 11 juli). Is er ná die bestanden nog iets aan het formaat gewijzigd, dan heb ik dat niet kunnen zien — de aangehaalde brenno/Keiko beschrijft presentatie-import (.pptx/.odp/.key) en bevat niets over OpenKAT-JSON.

Raakt #767 en de OpenKAT-helft van #772.

Co-Authored-By: Claude Opus 4.8 noreply@anthropic.com

Generated with Claude Code

Sluit het gat tussen wat de OpenKAT-import beloofde en wat hij deed, en zet hem op de plek waar hij hoort. ## De import las het verkeerde formaat De importlaag was geschreven zonder een echte export bij de hand: hij zocht `systems` en `findings` náást elkaar op het hoogste niveau. Zo ziet geen enkele OpenKAT-export eruit. Getoetst tegen zes echte exports kwam er een leeg deck uit — de bestanden werden wél "herkend", maar leverden nul systemen en nul bevindingen. Elke export heeft één envelop (`{organization_code, organization_name, organization_tags, data}`); het verschil zit in `data`: een vlakke samenvatting van de hele organisatie, of gesleuteld op rapporttype en daarbinnen op object. Beide worden nu gelezen. Wat daarbij aan het licht kwam: - **Bevindingen zitten in de deelrapporten**, niet in `findings-report` — die is in echte exports leeg. Vier van de zes bestanden hadden anders nul bevindingen opgeleverd terwijl er 284 in zaten. - **De noemer ging verloren**, waardoor `OpenKatControlScore.ratio` per definitie null was en de aggregator geen trend kón berekenen. - **Herimport was niet reproduceerbaar**: het organisatierapport draagt zelf geen datum en viel terug op `DateTime.now()`. De trendlijn werd zo een grafiek van het aantal keren dat je op Importeren drukte. - **De datumstempel van de exportknop werd niet gelezen** (`<organisatie>_20260319200604.json` — veertien cijfers zonder scheidingstekens). - **`name` is geregeld null** in echte exports; dat gaf "null" op de dia. ## En de plek waar het hoort Vierde optionele module, standaard uit, plus een nieuw tabblad **Integraties** met de rapportagemap. De import gebruikt die map rechtstreeks in plaats van er elke keer om te vragen. Reveal = module aan óf map aangewezen, zodat uitzetten een bestaand OpenKAT-deck niet onbijwerkbaar maakt. ## Verantwoording - Getoetst tegen zes echte exports: 6 van 6 herkend, 15 dia's met echte inhoud. Die bestanden staan **niet** in de repo — het zijn scangegevens van echte organisaties; de fixtures dragen de vorm met verzonnen namen. - Twee klasseplafonds tripten; beide opgelost door er gedrag uit te halen, niet door de basislijn te verhogen. Het Integraties-paneel is daarom een losse widget geworden in plaats van een `part` — de scheiding die #631 voor deze dialoog wilde. - De zoektoets kende alleen `_xxx()`-bouwers als tabbladinhoud; een tabblad dat door een losse widget wordt gerenderd viel stil buiten de telling. Nu herkent hij beide vormen. - 10 nieuwe strings x 31 talen; "OpenKAT" als leenwoord. - `make check` groen: 6196 toetsen, dekking 86,4%. ## Openstaand Deze PR bouwt op het formaat van de exports die nu voorhanden zijn (maart en 11 juli). Is er ná die bestanden nog iets aan het formaat gewijzigd, dan heb ik dat niet kunnen zien — de aangehaalde `brenno/Keiko` beschrijft presentatie-import (.pptx/.odp/.key) en bevat niets over OpenKAT-JSON. Raakt #767 en de OpenKAT-helft van #772. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Generated with [Claude Code](https://claude.com/claude-code)
De importlaag was geschreven zonder een echte export bij de hand. Hij zocht
`systems` en `findings` náást elkaar op het hoogste niveau; zo ziet geen
enkele OpenKAT-export eruit. Getoetst tegen zes echte exports kwam er dus een
leeg deck uit: de bestanden werden wél "herkend", maar leverden nul systemen
en nul bevindingen.

Elke export heeft één envelop — `{organization_code, organization_name,
organization_tags, data}` — en het verschil zit uitsluitend in `data`:

* **organisatierapport**: één vlakke samenvatting (`systems`, `findings`,
  `basic_security`, `total_*`);
* **assetrapporten**: gesleuteld op rapporttype en daarbinnen op OOI, met per
  OOI een blok `{data, template, report_name, …, created_at}`.

De twee speculatieve adapters zijn vervangen door adapters tegen die twee
vormen. Wat daarbij aan het licht kwam en is rechtgezet:

- **Bevindingen zitten in de deelrapporten**, niet in `findings-report` — die
  is in echte exports leeg. Vier van de zes bestanden hadden anders nul
  bevindingen opgeleverd terwijl er 284 in zaten.
- **De noemer ging verloren.** `controlScores` gaf alleen het aantal conforme
  systemen, waardoor `OpenKatControlScore.ratio` per definitie null was en de
  aggregator geen enkele trend kón berekenen. OpenKAT levert de noemer gewoon
  mee (`number_of_ips` naast `number_of_compliant`).
- **De datumstempel werd niet gelezen.** OpenKAT exporteert als
  `<organisatie>_20260319200604.json`; de uitdrukking eiste scheidingstekens
  en liet juist die vorm liggen.
- **Herimport was niet reproduceerbaar.** Het organisatierapport draagt zelf
  geen datum en viel terug op `DateTime.now()` — elke herimport gaf een nieuwe
  momentopname, en de trendlijn werd een grafiek van het aantal keren dat je
  op Importeren drukte. Nu de wijzigingsdatum van het bestand.
- **`name` is in echte exports geregeld null** (KAT-NO-SECURITY-TXT); dat gaf
  "null" op de dia. Nu valt hij terug op de id.

15 nieuwe toetsen over beide vormen; de bestaande toetsen draaien nu op de
echte envelop in plaats van op een verzonnen indeling.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
OpenKAT is een specifiek product en een specifieke werkwijze; wie een
presentatie komt maken heeft er niets aan en hoort er geen menu-item van te
zien. Het wordt daarom de vierde optionele module, standaard uit — met
dezelfde vaste regel als de drie ervóór: uitzetten mag bestaand werk nooit
onbereikbaar maken.

- **Uitbreidingen → OpenKAT**, harde standaard uit (eigen prefs-sleutels die
  nooit hernoemen). Bewust géén afgeleide van de inhoud zoals bij Online
  opslag: die inhoud bestond al vóór de module, deze niet.
- **Nieuw tabblad Integraties** met de rapportagemap. Het tabblad hangt aan de
  module: zolang OpenKAT de enige integratie is, is een leeg tabblad
  "Integraties" geen informatie maar ruis.
- **De import gebruikt die map rechtstreeks.** Een OpenKAT-overzicht wordt
  telkens opnieuw bijgewerkt uit dezelfde exportmap; elke keer dezelfde map
  aanwijzen is werk dat de app zelf kan onthouden. Zonder ingestelde map komt
  de mapkiezer als vanouds.
- **Reveal = module aan óf map aangewezen**, zodat een bestaand OpenKAT-deck
  bij te werken blijft nadat de schakelaar uitgaat.

11 toetsen over de stand, de poort, het tabblad en de vaste map.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Tien nieuwe bronstrings × 31 talen; "OpenKAT" is een productnaam en staat op
de leenwoordenlijst in plaats van vertaald te worden.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
docs(openkat): module, Integraties en het echte exportformaat vastgelegd
All checks were successful
ci / gate (pull_request) Successful in 22m27s
6a6ccae3de
USER_GUIDE zegt nu waar de schakelaar en de rapportagemap zitten, welke twee
exportvormen worden gelezen, en waar de momentopnamedatum vandaan komt —
inclusief waarom die nooit "nu" is. SOURCE_MAP registreert de nieuwe provider,
de modulekaart, het Integraties-paneel en de adapterlaag. CHANGELOG legt uit
wat er mis was en waarom het meer was dan een sleutelnaam.

Twee klasseplafonds tripten onderweg; beide zijn opgelost door er werkelijk
gedrag uit te halen in plaats van de basislijn te verhogen. Het
Integraties-paneel is daarom een losse widget geworden in plaats van een
`part` — precies de scheiding die #631 voor deze dialoog wilde.

En de zoektoets kende alleen `_xxx()`-bouwers als tabbladinhoud, waardoor een
tabblad dat door een losse widget wordt gerenderd stil buiten de telling zou
vallen. Hij herkent nu beide vormen, zodat de Integraties-ingang echt gedekt
is in plaats van overgeslagen.

make check groen: 6196 toetsen, dekking 86,4%.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
refactor(uitbreidingen): "Importeren" als module, met OpenKAT als eerste bron
All checks were successful
ci / gate (pull_request) Successful in 22m8s
4d5058a85f
Besluit B1 van #772: één module voor élke bron waaruit OciDeck materiaal
binnenhaalt, niet één per product. Voor de gebruiker is "ik haal er iets van
buiten in" één gedachte; een schakelaar per importeur zou het
Uitbreidingen-tabblad laten groeien met keuzes die niemand los wil maken.

De naamswijziging dwong een scheiding af die klopt, en die is nu ook echt
aangebracht in plaats van alleen in de naam:

- **`import_module_provider.dart`** draagt de schakelaar. Het uitbreidpunt is
  `importerContentProviders`: een nieuwe importeur zet daar zijn eigen "heb ik
  al inhoud"-provider bij en erft daarmee de vaste regel — tonen zodra de
  inhoud er is. Bewust een lijst en geen steeds langere `||`, zodat op één
  plek staat wát er als inhoud telt en een importeur er niet stil buiten valt.
- **`openkat_provider.dart`** houdt alleen nog de rapportagemap over: de
  schakelaar beantwoordt "hoort importeren bij mijn werk", dit bestand
  beantwoordt "waar staan mijn OpenKAT-bestanden".

De prefs-sleutel van de schakelaar heet nu `importModuleEnabled`. Dat mag
alleen nu: de module staat nog niet op main, dus er is geen installatie die
hem draagt. Hierna niet meer — daar staat de reden bij de constante.

Verder: het OpenKAT-logo staat bij de sectie op Integraties (bewust het logo
en niet de mascottefoto van Over OciDeck), teruggeschaald naar 384px voor de
bundel. Een toets bewaakt het assetpad, want een verkeerd pad rendert stil een
foutvak. Drie nieuwe strings × 31 talen.

make check groen: 6196 toetsen, dekking 86,4%.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
brenno merged commit 74b266b254 into main 2026-07-24 09:18:08 +00:00
Sign in to join this conversation.
No description provided.