Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
1a352df
feat: add shared Studio-based codebook components and generator
jurei733 Sep 28, 2026
be4f169
ci: verify shared codebook contracts and document integration
jurei733 Sep 28, 2026
d8964b4
fix: keep host-specific filters outside shared codebook options
jurei733 Sep 28, 2026
853c733
fix: exclude invisible-only codebook instructions
jurei733 Sep 28, 2026
2153707
fix: preserve nested codebook formatting and word spacing
jurei733 Oct 5, 2026
d0179ae
fix: lock codebook selection while loading and report invalidated IDs
jurei733 Oct 5, 2026
2464df3
merge: update shared codebook from master
jurei733 Oct 5, 2026
fc71cea
feat: share codebook training filter and Studio group column
jurei733 Oct 5, 2026
d998221
fix: expose accessible codebook checkbox labels
jurei733 Oct 5, 2026
8217bb8
fix(codebook): preserve loose instruction text and list contents
jurei733 Oct 5, 2026
fd83cae
fix: preserve Studio layout for whitespace-only instructions
jurei733 Oct 12, 2026
d8b8316
test: cover codebook option matrix against original Studio exports
jurei733 Oct 12, 2026
946585e
test: compare host installations and prepare Windows Word acceptance
jurei733 Oct 12, 2026
aa404bc
fix: preserve protected spaces in Studio codebook exports
jurei733 Oct 13, 2026
d9182dc
test: retain synthetic documents for Office rendering acceptance
jurei733 Oct 13, 2026
88507b0
test: add original Studio documents for Office comparison
jurei733 Oct 13, 2026
6bfa2ca
test: include immutable Studio Office baselines
jurei733 Oct 13, 2026
2925485
test: cover shared editor formatting combinations
jurei733 Oct 13, 2026
764a1a4
test: retain actual queued codebook browser download
jurei733 Oct 13, 2026
2617b45
docs: record Office and host browser acceptance results
jurei733 Oct 13, 2026
1b821b7
test: capture browser-authored formatting regression document
jurei733 Oct 13, 2026
0607ba5
test: add synthetic editor and player Word acceptance matrices
jurei733 Oct 13, 2026
d195c08
test: capture real toolbar and styled formula Word exports
jurei733 Oct 13, 2026
e9cf4ad
test: capture compound formula rendering before correction
jurei733 Oct 13, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,9 @@ jobs:
CI: true
run: npm run test:coverage

- name: Build shared library and verify codebook contracts
run: npm run build_cc && npm run test:codebook

- name: Coding-scheme validation script
run: npm run test:scheme

Expand Down
120 changes: 120 additions & 0 deletions docs/codebook-acceptance-2026-10-13.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
# Codebook-Abnahme vom 13.10.2026

Die P2-Regression bei geschützten und wiederholten Leerzeichen ist behoben.
Die bisherige Studio-Ausgabe bleibt in den stabilen Referenzfällen erhalten;
die direkten Studio- und die asynchronen Kodierbox-Exporte liefern identische Dokumentinhalte.

## Automatisierte Nachweise

| Prüfung | Ergebnis |
| --- | --- |
| Generator | 1.206 Tests bestanden, keine übersprungen |
| Neue Editor-Matrix | 384 Kombinationen, jeweils ESM und CommonJS, allgemeine und Code-Instruktionen |
| Ursprüngliches Studio | 32 bestehende + 20 neue unabhängige JSON-/DOCX-Referenzfälle |
| Installierte Hosts | 4.654 Exportpaare: JSON und alle relevanten DOCX-Bestandteile identisch |
| Studio | 49 API- und 66 Frontendtests bestanden |
| Kodierbox | 58 Backend- und 60 Frontendtests bestanden |
| Builds | Bibliothek und alle vier Host-Builds erfolgreich |
| Lint | Keine Fehler; Bibliothek 18, Studio API 6 bestehende Warnungen |

Alle 20 neuen Leerzeichenfälle waren vor dem Fix rot und danach grün.
Die vollständigen Host-Suiten wurden für diesen Fix nicht erneut ausgeführt.
Referenz: ursprünglicher Studio-Commit `2504265721a59c7c65425072951ce82ab16f0fb8`.
Die Laufzeitänderungen wurden mit Bibliothek `aa404bc2`, Studio `b12fd461`
und Kodierbox `92b88f30` geprüft; spätere Ergänzungen betreffen Tests, synthetische
Abnahmedokumente und Dokumentation.

Paket: identischer lokal gepackter 4.1.0-Tarball in beiden Anwendungen.
SHA256: `dcee6cc39436baf91cf2558afedfbc202e044ca14dbf72c7bfdf4b381e5c0ccd`.
Alle installierten Paketdateien wurden mit dem Tarball verglichen; beide
Root-Locks und Studios API-Runtime-Lock enthalten dessen neue Integrität.

## Echte Browserabläufe

Beide gebauten Frontends wurden über einen lokalen Static-/API-Proxy mit ihren
unveränderten produktiven NestJS-Bundles ausgeführt. Die PostgreSQL-Datenbanken
wurden mit den vollständigen Repository-Migrationen frisch angelegt. Studio
verwendete Liquibase 4.33, Kodierbox die vorgesehene Version 4.28. Kodierbox nutzte
echtes Redis/Bull und einen isolierten Keycloak mit zwei synthetischen Identitäten.
Die Fixture-Einrichtung erfolgte über echte APIs; Kodierbox-VOCS und die
Jobdefinition wurden als erfundene Datensätze direkt in die Testdatenbank gesetzt.
Die erfolgreichen Exportabläufe enthielten keine API-/Auth-/Queue-Mocks.

- **Studio:** JSON-/DOCX-Download, leere Auswahl gesperrt, Suche erhält Gesamtauswahl,
Dialog schließt nach Download, anonymer Zugriff 401, fremder Workspace 403,
Missing-Code 0 über reales Profil, Score-Abwahl und Schulungsfilter geprüft.
- **Kodierbox:** JSON-/DOCX über echte Jobanlage, Statusabfrage und Download;
Jobdefinitionspicker beschränkt auf A/ALIAS_00, ausgewähltes Missingprofil und
Score-Abwahl stimmen mit dem Download überein. Doppelauslösung ist gesperrt;
erneuter Versuch und Ende des Pollings beim Schließen funktionieren.
- **Fehlerzweige:** Studio-Exportfehler sowie Kodierbox-Anlage-, Status- und
Downloadfehler wurden gezielt im Browsernetzwerk injiziert. Meldung und
Freigabe für erneuten Versuch wurden geprüft; erfolgreicher Retry lief wieder
gegen die echte Queue.
- **Reale Zugriffsprüfungen:** Kodierbox weist anonyme und nicht zugewiesene Nutzer
ab (bestehender WorkspaceGuard: 401), fremde Job-Workspaces mit 403, fremde
ausgewählte Einheiten mit 404 und ungültiges Format/Boolean mit 400. Ein
erfolgreicher Download räumt sein Ergebnis auf; Folgeabruf liefert 404.
- Beide erfolgreichen Browser-Downloads sind in JSON und allen normalisierten
DOCX-Bestandteilen identisch. NBSP, schmales NBSP und doppelte Abstände bleiben
erhalten. Keine unbehandelten Browser-Ausnahmen in den bestandenen Abläufen.

Testumgebung: PostgreSQL 16.11, Redis 7.4, Keycloak 26.7.3. Das ist keine
Produktions- oder Deployment-Abnahme; Kodierboxs PostgreSQL-14-Produktionsversion
wurde damit nicht separat geprüft. Der vorhandene Keycloak-JS-Adapter 23.0.7
benötigte im Testrealm den dokumentierten Nonce-Kompatibilitätsmapper
([Keycloak Upgrade Guide](https://www.keycloak.org/docs/26.7.5/upgrading/index.html)).
Alle isolierten Testdienste wurden anschließend beendet und entfernt.

## Microsoft Office

Die tatsächlichen DOCX-Dateien wurden von **Microsoft Office Web Viewer / Word**
gerendert, ohne Office-Anmeldung. Es wurden ausschließlich erfundene, im
Bibliotheksbranch versionierte Testdokumente verwendet.

| Dokument | Seiten |
| --- | ---: |
| Aktuelles Rich-Text-Dokument mit Scores | 3 |
| Ursprüngliches Studio mit Scores | 3 |
| Aktuelles Rich-Text-Dokument ohne Scores | 3 |
| Ursprüngliches Studio ohne Scores | 3 |
| Tatsächlicher Studio-Browser-Download | 3 |
| Tatsächlicher Kodierbox-Browser-Download | 3 |
| 48 Markierungskombinationen plus Formel/Listen/Bild | 2 |
| **Gesamt** | **20** |

Tabellenspalten, Umbrüche, Bilder, Formeln, Markierungen und Fußzeilen/Seitenzahlen
wurden anhand der gerenderten Seiten geprüft. Alle sechs Seiteninhalte der
aktuellen/ursprünglichen Studio-Paare sind pixelgleich (Seitenbereich oberhalb
der Fußzeile; die vereinbarte Umbenennung zu „IQB Codebook“ wird separat geprüft).
Die beiden echten Browser-Dokumente sind auf allen drei vollständigen Seiten
pixelgleich. Es traten keine sichtbaren abgeschnittenen Inhalte oder defekten
Formeln/Bilder auf. Dies ist ein echter Microsoft-Word-Web-Nachweis; Windows-
oder macOS-Desktop-Word wurde nicht ausgeführt.

## Aspect-Abgleich und Grenzen

Quellabgleich mit `iqb-berlin/verona-modules-aspect@fb3f5982`: Die 384 Tests
umfassen alle Kombinationen der gemeinsamen vier Textmarkierungen, drei gültigen
Grundlinienzustände, zwei Verschachtelungsreihenfolgen und vier Ausrichtungen.
Der Codebook-Vertrag liest Kodierinstruktionen aus VOCS, nicht vollständige
Aspect-Aufgaben mit interaktiven Player-Elementen. Aspect-Formelknoten verwenden
einen anderen Vertrag als die IQB-Formeln des Instruktionseditors. Ein kompletter
Aspect-Editor-/Player-Browserlauf wurde nicht durchgeführt.

Die bestehenden Studio-Grenzen bei CSS-Listenstilen, verschachtelten
Listeneinrückungen, Bild-Floats sowie innerhalb eines Absatzes wechselnder Farbe/
Schriftgröße bleiben dokumentiert. Eine uneingeschränkte HTML-/CSS-Layouttreue
oder Unterstützung aller Aspect-Player-Knoten wird nicht behauptet.

## Veröffentlichung und CI

Alle drei Branches `shared-codebook` wurden committed und gepusht. Die offenen
PRs #239 (Bibliothek) und #1041 (Kodierbox) werden mit diesen Ergebnissen aktualisiert.
Studio-PR #1728 ist ohne Merge geschlossen; der Studio-Branch wurde aktualisiert.
Bibliotheks-CI war für `2925485` vollständig grün. Die CI der abschließenden
Dokumentationscommits wird separat angegeben. Kodierboxs zuletzt geprüfte
GitLab-Pipeline [103668](https://scm.cms.hu-berlin.de/iqb/coding-box/-/pipelines/103668)
für `92b88f30` ist fehlgeschlagen; die Jobursache bleibt hinter Bot-Schutz/
Anmeldung unbestätigt. Lokale grüne Tests ersetzen diesen offenen CI-Status nicht.
Kein Merge, Release, Paket-Publish oder Rollout wurde ausgeführt.
169 changes: 169 additions & 0 deletions docs/shared-codebook.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,169 @@
# Gemeinsames Codebook: Integrationsvertrag

Studio ist die Referenz für Bedienung und Dokumentlayout. Die drei Einstiegspunkte
`codebook-models`, `codebook-generator` und `codebook-export` trennen Daten,
frameworkfreie Dokumenterstellung und Angular-Oberfläche. Die Bibliothek enthält
keinen Jobvertrag, keine HTTP-Aufrufe und keinen Download-Dienst.

## Anwendungen

Studio lädt Aufgaben und Missingprofile, übergibt die aktive Aufgabe und seine
Speichersperre und verarbeitet `exportRequested` mit seinem direkten API-Aufruf.
Schulungsbedarf ist eine gemeinsame Auswahl und wird in beiden Anwendungen durch
denselben Generator anhand von CODER_TRAINING_REQUIRED gefiltert.
Die Kodierbox ergänzt ihren Jobdefinitionsfilter über `[codebookFilters]` und zeigt ihre
Jobzustände über `[codebookStatus]`. Das sind Projektionsflächen ohne Jobsemantik.
`loading` und `busy` sind allgemeine Sperrzustände. Nur die Kodierbox startet Jobs,
fragt Status ab und lädt Ergebnisse. Beim Schließen endet die Statusabfrage;
der Serverjob wird nicht abgebrochen.

Die Übersetzungen der Oberfläche stehen im Host unter `codebook.*`. Beide Hosts
verwenden dieselben Studio-Beschriftungen und Tooltips. `selectionChanged`,
`exportRequested` und `cancel` sind die einzigen Ausgaben. Der Exportwunsch enthält
Aufgaben-IDs, fachliche Optionen und Missingprofil-ID. Die Profile tragen eine
numerische ID und eine Beschriftung; 0 bedeutet kein Profil.
`showGroupColumn` ist im Studio aktiv, in Kodierbox deaktiviert.
Während `loading` und `busy` ist jede Auswahl gesperrt. Verliert eine Aufgabe ihre
Verfügbarkeit, meldet selectionChanged auch die bereinigte Auswahl zurück.
Variablenbündel bleiben als bestehender Kodierbox-API-Vertrag erhalten, werden
aber im Codebook-Dialog nicht mehr angeboten (Issue #176).

## Bewusste fachliche Korrekturen

* Nur manuell: Variablen mit regulären manuell beschriebenen Codes; nur diese Codes.
* Nur geschlossen: Variablen mit RESIDUAL_AUTO oder INTENDED_INCOMPLETE; alle Codes.
* Beide: Vereinigung dieser Variablengruppen; alle Codes.
* Beide aus: keine Einschränkung nach dieser Kategorie.
* Nur mit Codes wird nach der Codeauswahl ausgewertet.
* Leere HTML-Strukturen, unsichtbare Zeichen und Leerzeichen sind keine Instruktion;
unterstützte Bilder und Formeln sind eine Instruktion. Allgemeine Instruktionen
allein machen keinen Code manuell.
* Code 0 und Missing 0 bleiben erhalten. Missing-Codes behalten ihren JSON-Datentyp
aus dem Profil (Zahl oder Zeichenkette); Kodierbox wandelt Zahlen nicht mehr in
Zeichenketten um. Leere Exporte liefern `[]` bzw. ein gültiges
DOCX. Fehlerhafte Schemen melden die betroffene Aufgabe.
* Aufgaben werden nach Schlüssel, Variablen nach Alias/ID sortiert; Codefolge bleibt.
* Schulungsbedarf: alle, nur mit oder nur ohne CODER_TRAINING_REQUIRED; kombiniert
mit der gemeinsamen Variablen-/Codeauswahl.
* BASE_NO_VALUE bleibt ausgeschlossen; abgeleitete Variablen folgen der Option.
* Itembeziehungen sind explizite `{id, variableId}`-Paare. Der Anwendungsadapter
normalisiert Quell-IDs auf die im Dokument verwendeten Aliase.
* Die Kennzeichnung lautet IQB Codebook. Studio-Formatierung, Tabellen, Seitenfelder,
eingebettete Bilder und Formelkonvertierung bleiben erhalten. Klartextinstruktionen
und Leerzeichen an Formatgrenzen werden nicht mehr verschluckt. Verschachtelte
Textmarkierungen bleiben kombiniert erhalten. Direkte Listentexte und Klartext
vor, zwischen und nach HTML-Absätzen werden in Quellreihenfolge übernommen;
bestehende Absatzinhalte, Bilder und Formeln erscheinen weiterhin genau einmal.

## Paket und Laufzeit

`npm run build_cc` erzeugt Angular-ESM sowie einen zusätzlichen CommonJS-Einstieg
für Server. Der Generator braucht weder Angular noch DOM/Browser-Globals.
Der CommonJS-Build integriert den ausschließlich als ESM gelieferten mathml2omml-
Konverter. Dessen Quellcode bleibt über Source Maps und das npm-Original verfügbar.

Die Regeltextkonvertierung ist intern auf @iqb/responses 5.2.2 festgelegt.
Das ist ausdrücklich kein Upgrade der Kodierbox-Kodierengine: deren responses
5.2.0 und response-Spezifikation 1.5.1 bleiben unverändert. Die Bibliothek akzeptiert
response-Spezifikation 1.5.1 sowie 2.x als Peer.

## Lokale Integration und Veröffentlichung

Die beiden Integrationen referenzieren dieselbe gepackte Datei unter
`vendor/iqb-ngx-coding-components-4.1.0.tgz`. Das ist ein lokal prüfbarer Release-
Kandidat, noch keine veröffentlichte npm-Version. Zum Release wird genau der
abgenommene Bibliotheksstand veröffentlicht; danach werden die Host-Abhängigkeiten
auf die Registry-Version umgestellt und Locks neu geprüft. Die lokalen Tarballs
können dann entfernt werden. Beide Anwendungen gemeinsam abnehmen und ausrollen.
Rollback: vorherige Bibliotheks-/Anwendungsversion; keine Datenmigration.

## Prüfungen

* `npm run test:codebook`: Node-Vertragstests für alle Filterkombinationen, Daten,
JSON, DOCX-Struktur, Bilder, Formeln, Itembeziehungen und CJS/ESM-Gleichheit.
* `npm run test:cc`: Angular-Tests einschließlich Auswahl/Suche/Sperrzustände.
* Beide Hosts testen ihre echten Adapter und bestehenden Formelregressionen.
* Die künstlichen Fälle in `scripts/fixtures/codebook-synthetic.mjs` enthalten keine
Aufgabeninhalte aus den Beispiel-ZIPs. Die Matrix durchläuft alle 256 Kombinationen
der acht Ja/Nein-Optionen, drei Schulungsfilter, drei Missing-Konstellationen und
beide Formate: 4.608 Exporte. Alle neun Quelltypen werden in der Datenauswahl geprüft.
* 32 zusätzliche Referenzfälle vergleichen Rohschema → JSON und sämtliche relevanten
DOCX-Bestandteile mit dem ursprünglichen Studio. Die Referenz wird ausschließlich
aus dem dokumentierten alten Studio-Commit erzeugt, niemals aus dem neuen Generator.
* Weitere 20 Studio-Referenzfälle erhalten NBSP, schmale geschützte Leerzeichen und
wiederholte Abstände in allgemeinen und Code-Instruktionen, jeweils mit und ohne
Score-Spalte. HTML-Zeichenreferenzen, Unicode und fett formatierter Text werden
über ESM und CommonJS auf exakte Inhalte und alle DOCX-Bestandteile geprüft.
* `node scripts/compare-codebook-installations.mjs STUDIO_ROOT BOX_ROOT OUTPUT_DIR`
prüft dieselbe Matrix über Studios DownloadWorkspacesClass und Kodierboxs echten
Generation-Service samt Adapter mit Datenquellen im jeweiligen Anwendungsformat.
Nur Datenbank-/Profilzugriffe werden im Speicher bereitgestellt. Der Vergleich
schließt Bilder, Beziehungen, Styles, Fußzeilen und Missing-Datentypen ein.
Zusätzlich laufen die 20 Abstandsreferenzen in beiden Formaten gegen das alte
Studio; zusammen werden 4.654 Exportpaare verglichen.
Das ist ausdrücklich kein HTTP-, Browser-, Berechtigungs- oder Redis-End-to-End-Test.
* Studio-Frontend prüft direkten Export, Ladezustände, Fehlermeldung und Speichersperre.
* Kodierbox prüft Scope-Filter, wiederholte Starts, langsame Statusabfragen und Schließen.
* Frontend- und Backend-Prüfungen auf dem Entwicklungsrechner nacheinander ausführen.
* Vor Ausrollen bleiben visuelle Mehrseiten-DOCX-Abnahme und Host-Browserabläufe
einschließlich Netzwerkprüfung verpflichtend.

### Microsoft Office

Microsoft Office Web Viewer / Word hat am 13.10.2026 sieben ausschließlich
synthetische Dokumente mit insgesamt 20 Seiten gerendert. Die Host-Browser-
Downloads sind auf allen drei vollständigen Seiten pixelgleich. Die alten und
neuen Studio-Rich-Text-Dokumente sind mit/ohne Scores in ihren sechs
Seiteninhalten pixelgleich; die vereinbarte Fußzeile wird separat geprüft.
Details und Grenzen: [Abnahmeprotokoll](./codebook-acceptance-2026-10-13.md).

XML-Gleichheit und LibreOffice-Rendering allein ersetzen keinen Office-Nachweis.
Für einen zusätzlichen Windows-Desktop-Word-Abnahmeweg legt der
Installationsvergleich künstliche Exporte
sechs DOCX-Dateien und `word-expectations.json` im Ausgabeverzeichnis ab: je Anwendung
einen Filter-/Missing-0-Fall sowie Rich-Text-Fälle mit und ohne Score-Spalte. Die
Rich-Text-Fälle werden zusätzlich direkt gegen die alte Studio-Referenz geprüft.
Auf einem Windows-Rechner mit Desktop-Word:

```powershell
./scripts/verify-codebook-word-windows.ps1 -Directory C:\Codebook-Pruefung
```

Das Skript öffnet alle Dateien regulär und schreibgeschützt, aktualisiert Felder,
prüft Textgleichheit, Seitenzahl, Tabellen, ungeteilte Zeilen, Bilder, Formeln und
Fußzeilen und exportiert sechs PDFs. Es speichert Word-Version und Build im Ergebnis.
Anschließend alle gerenderten Dokumente vollständig visuell prüfen: insbesondere
Spaltenbreiten, Umbrüche, Formeln, Bilder, Schriften und „Seite X von Y“.
`visualAcceptanceComplete` bleibt bis zur tatsächlichen visuellen Abnahme false.
Eine nicht ausgeführte Windows-Prüfung darf nicht als bestanden gemeldet werden.

### Editor-/Player-Abgleich und Formatkombinationen

Die Instruktionen des coding-components-Editors sind der Eingabevertrag des
Codebook-Exports. Die Extension-Liste wurde mit Aspect Editor/Player bei
`iqb-berlin/verona-modules-aspect@fb3f5982` abgeglichen. Der Export liest
Kodierschemata (`manualInstruction`), nicht die vollständige Aspect-Aufgabe mit
interaktiven Player-Elementen.

`codebook-editor-matrix.test.mjs` prüft alle 384 Kombinationen aus vier
Textmarkierungen (Fett, Kursiv, Unterstrichen, Durchgestrichen), drei gültigen
Grundlinienzuständen, zwei Verschachtelungsreihenfolgen und vier Ausrichtungen.
Jeder Fall prüft allgemeine und Code-Instruktion, geschützte und wiederholte
Leerzeichen, Formatierungsgrenzen sowie identische ESM-/CommonJS-Dokumentteile.
Diese Matrix ergänzt die 52 unabhängigen Alt-Studio-Referenzfälle.

`node scripts/create-codebook-editor-office-fixture.mjs` erzeugt ein ausschließlich
synthetisches Dokument mit allen 48 Markierungskombinationen sowie gemischten
Formel-, Listen- und Bildfällen zur visuellen Office-Abnahme.

Grenzen des bestehenden Studio-Renderers bleiben sichtbar: CSS-Listenstile,
verschachtelte Listeneinrückungen, Bild-Floats und pro Textlauf wechselnde
Farbe/Schriftgröße werden nicht vollständig wie im Browser abgebildet. Der
Abgleich behauptet deshalb keine vollständige HTML-/CSS-Layouttreue.
Aspect-spezifische Formelknoten (`aspect-nodeview-math-formula[formula]`) und
interaktive Cloze-Knoten sind ein anderer Vertrag als
`span.iqb-math-formula[data-latex]` bzw. `[[iqb-math:…]]` in Kodierinstruktionen.
Der Aspect-Player rendert seine gespeicherten Formeln über
`projects/common/utils/math-formula-markup.ts`; der Codebook-Export nutzt OMML.
Ein vollständiger Aspect-Editor-/Player-Lauf ist damit nicht durch diese
Codebook-Matrix ersetzt.
Loading
Loading