Initialize Article Data Manager project

This commit is contained in:
2026-07-29 10:53:21 +02:00
commit 83639b9957
51 changed files with 1100 additions and 0 deletions
+20
View File
@@ -0,0 +1,20 @@
# ADR 0001 - Eigenstaendiges Repository
## Status
Akzeptiert
## Entscheidung
Der Article Data Manager wird als eigenstaendiges Projekt gefuehrt und nicht in das RollCalc-Repository integriert.
## Begruendung
- getrennte Verantwortlichkeiten
- unabhaengige Entwicklung
- Schutz des RollCalc vor Import- und Datenpflegekomplexitaet
- spaetere Wiederverwendung durch weitere Systeme
## Konsequenzen
RollCalc konsumiert nur ein definiertes Exportartefakt. Schnittstellen und Formatkompatibilitaet muessen dokumentiert und getestet werden.
+17
View File
@@ -0,0 +1,17 @@
# ADR 0002 - Trennung der Datenquellen
## Status
Akzeptiert
## Entscheidung
ERP-Daten, bestehende RollCalc-Daten, manuelle Daten und generierte Daten werden physisch und logisch getrennt.
## Begruendung
Die Trennung macht Herkunft, Verantwortlichkeit und Konflikte nachvollziehbar. Sie reduziert das Risiko, produktive Quelldaten versehentlich zu veraendern oder generierte Ergebnisse als Primaerdaten zu behandeln.
## Konsequenzen
Importer und Merge-Logik muessen Quelle und Prioritaet explizit beruecksichtigen. Produktive Datenverzeichnisse werden nicht standardmaessig versioniert.
+19
View File
@@ -0,0 +1,19 @@
# ADR 0003 - Artikelnummer als Zeichenkette
## Status
Akzeptiert
## Entscheidung
Artikelnummern werden durchgaengig als Strings behandelt.
## Begruendung
- fuehrende Nullen
- keine mathematische Bedeutung
- moegliche zukuenftige alphanumerische Werte
## Konsequenzen
Importer duerfen Artikelnummern nicht in numerische Typen konvertieren. Normalisierung darf fuehrende Nullen nicht entfernen.
@@ -0,0 +1,17 @@
# ADR 0004 - Generierte Datei ist kein Primaerdatenbestand
## Status
Akzeptiert
## Entscheidung
Die erzeugte `article-data.json` ist ein Build-Artefakt. Aenderungen duerfen nicht direkt ausschliesslich in dieser Datei vorgenommen werden.
## Begruendung
Primaere Aenderungen gehoeren in ERP, bestehende RollCalc-Quelldaten oder manuelle Zusatzdaten. Nur so bleiben Herkunft, Validierung und Konflikte nachvollziehbar.
## Konsequenzen
`data/generated/article-data.json` wird nicht standardmaessig versioniert. Relevante Aenderungen muessen reproduzierbar aus den Quellen erzeugt werden.
+3
View File
@@ -0,0 +1,3 @@
# Architecture Decision Records
ADRs dokumentieren zentrale Architekturentscheidungen. Neue ADRs werden fortlaufend nummeriert und sollen Entscheidung, Kontext und Konsequenzen enthalten.
+58
View File
@@ -0,0 +1,58 @@
# Architektur
## Systemkontext
Article Data Manager ist ein lokales Werkzeug zur Erzeugung einer RollCalc-kompatiblen `article-data.json`. RollCalc ist ein externer Konsument und bleibt technisch getrennt.
## Verantwortlichkeiten
- Import vorhandener RollCalc-Artikeldaten.
- Import eines ERP-CSV-Exports.
- Import manuell gepflegter Zusatzdaten.
- Normalisierung technischer Formate, ohne fachliche Bedeutungen zu erraten.
- Validierung und Konflikterkennung.
- Deterministischer Export fuer RollCalc.
- Reports fuer Treffer, Nicht-Treffer, Konflikte und Validierungsfehler.
## Modulgrenzen
- `models`: interne Datenmodelle.
- `importers`: Lesen von JSON- und CSV-Quellen.
- `validation`: Format-, Typ- und Fachvalidierung.
- `merge`: Merge-Regeln, Konflikterkennung und Prioritaeten.
- `exporters`: Ausgabe der RollCalc-kompatiblen JSON-Datei.
- `cli`: spaetere Kommandozeile.
## Datenfluss
```text
data/source/erp/production-key-data.csv
data/source/rollcalc/article-data.json
data/manual/article-manual-data.csv
|
v
Import -> Normalisierung -> Validierung -> Merge -> Export
|
+--> data/reports/
+--> data/generated/article-data.json
```
## Datentrennung
Quelldaten, manuelle Daten und generierte Daten bleiben physisch und logisch getrennt. Produktive Dateien in `data/` und `incoming/` werden nicht versioniert.
## Erweiterbarkeit
Weitere Quellen sollen als eigene Importer angebunden werden. Jede Quelle muss Originalfeldnamen, Einheiten, Prioritaet und Konfliktverhalten dokumentieren.
## Spaetere Weboberflaeche
Eine lokale Weboberflaeche ist erst nach einem reproduzierbaren CLI-Merge sinnvoll. Sie soll manuelle Zusatzdaten pflegen, ERP-Werte anzeigen und Eingaben validieren, aber keine Quelldaten direkt ueberschreiben.
## Spaetere Datenhaltung
Phase 4 kann SQLite als lokale Datenbasis einfuehren. PostgreSQL ist nur sinnvoll, wenn Mehrbenutzerbetrieb, zentrale Freigaben oder Integrationen dies tatsaechlich erfordern.
## RollCalc als externer Konsument
RollCalc konsumiert ausschliesslich die exportierte `article-data.json`. Aenderungen am Ausgabeformat muessen mit der RollCalc-Kompatibilitaet abgeglichen und dokumentiert werden.
+71
View File
@@ -0,0 +1,71 @@
# Datenwoerterbuch
## Zielmodell
| Feld | Bedeutung | Datentyp | Einheit | Quelle | Pflichtstatus | Zulaessige Werte | Override-Regel | Validierungsregel |
| --- | --- | --- | --- | --- | --- | --- | --- | --- |
| `nr` | Artikelnummer | String | keine | Matching-Schluessel aus allen Quellen | Pflicht | nicht leer, fuehrende Nullen erlaubt | kein Override | muss String bleiben, trimmen erlaubt |
| `name` | Artikelbezeichnung | String oder null | keine | ERP, alternativ RollCalc | offen fuer Export | beliebiger Text | manuell nur nach expliziter Freigabe | nicht stillschweigend bei Konflikt ueberschreiben |
| `width` | fuer RollCalc relevante Produktbreite | Float oder null | m | vermutlich ERP, genaue Spalte offen | optional bis bestaetigt | >= 0, Einheit zu klaeren | kein manueller Override in Phase 0 | Dezimalformat erkennen, Einheit dokumentieren |
| `thickness` | Dicke fuer Berechnung | Float oder null | mm | RollCalc | optional bis RollCalc-Pflichten geklaert | >= 0 | manueller Override noch offen | `0` nicht automatisch als unbekannt werten |
| `area_weight` | Flaechengewicht | Float oder null | g/m2 | RollCalc oder manuell | optional | >= 0 | manueller Override vorgesehen | `0` nicht automatisch als unbekannt werten |
| `core_diameter` | Kerndurchmesser | Integer oder null | mm | manuell | optional | positive mm-Werte | manuelle Pflege vorgesehen | muss getrennt von `core_type` bleiben |
| `core_type` | Kernart | String oder null | keine | manuell; bisher RollCalc numerisch | optional | vorlaeufig `cardboard`, `steel`, weitere offen | manuelle Pflege vorgesehen | bisherige numerische Bedeutung offen |
## Manuelle CSV-Quelle
Vorgesehene erste Struktur:
```csv
nr;core_diameter;core_type;area_weight;comment
214700;100;cardboard;;Standard-Pappkern
229800;168;steel;;Grosser Stahlkern
```
`comment` dient als fachlicher Hinweis und wird nicht automatisch in die RollCalc-Ausgabe uebernommen.
## Beobachtete ERP-CSV-Struktur
Lokale Datei: `incoming/Liste Schluesseldaten Produktion.csv`, nicht versioniert.
- Encoding-Indiz: UTF-8 mit BOM.
- Delimiter: `,`.
- Datenzeilen: 1786.
- Mehrfachtreffer: 247 Artikelnummern kommen mehrfach vor.
- Dezimalformate: Kommawerte wie `"6,00"` und Punktwerte wie `1.548` wurden beobachtet.
Originalspalten:
| Originalspalte | Beobachtung | Vorlaeufige Beschreibung |
| --- | --- | --- |
| `SL_COMPANY_NO` | befuellt | offen; vermutlich Mandant/Firma |
| `PHG` | befuellt | offen |
| `PG` | befuellt | offen |
| `SL_ITEM_NO` | 1786/1786 befuellt | Artikelnummer, fachlich als Matching-Kandidat |
| `SL_ITEM_TEXT` | 1786/1786 befuellt | Artikeltext, fachliche Verwendung offen |
| `SL_QUANTITY_UNIT2` | befuellt | offen; Mengeneinheit |
| `SL_PART_CATEGORY_NO2` | befuellt | offen |
| `SL_PLANNING_FLAG2` | befuellt | offen |
| `qm` | teilweise leer | offen; Einheit/Bezugsmenge zu klaeren |
| `ROP_PRODUCT_WIDTH` | 775/1786 befuellt | Breitenkandidat; Bedeutung und Einheit offen |
| `ROP_RATE_OF_PRODUCTION` | 775/1786 befuellt | offen; Produktionsrate |
| `WPL_WORKPLACE_TEXT` | 893/1786 befuellt | offen; Produktionsarbeitsplatz |
| `SL_NUMBER_OF_PERSON_MASCHINE` | teilweise befuellt | offen |
| `SL_MINIMUM_PRODUCTION_QUANTITY` | beobachtet | offen |
| `SL_PRODUCTION_SPEED` | 893/1786 befuellt | offen; Produktionsgeschwindigkeit |
| `kg_qm` | 1595/1786 befuellt | offen; moeglicher Gewichtsbezug, Einheit zu klaeren |
| `SL_PRODUCTION_REJECT_QUOTE` | 1786/1786 befuellt | offen; Ausschussquote |
| `SL_SETUP_TIME_MASCHINE` | 893/1786 befuellt | offen; Ruestzeit |
| `SL_CALCULATED_LOT_SIZE` | beobachtet | offen |
| `PRCO_CALCULATION_DATE` | beobachtet | offen; Kalkulationsdatum |
| `PRCO_CALCULATION_TYPE` | beobachtet | offen |
| `PRCO_CALCULATION_NO` | beobachtet | offen |
| `PRCO_PRODUCTION_COSTS` | beobachtet | offen |
| `PRCO_COST_OF_MATERIAL_VARIABLE` | beobachtet | offen |
| `PRCO_MATERIAL_OVERHEAD_COSTS` | beobachtet | offen |
| `PRCO_EXTERNAL_COSTS` | beobachtet | offen |
| `PRCO_MANUFACTURING_COSTS_FIXED_VARIABLE` | beobachtet | offen |
| `PRCO_MANUFACTURING_OVERHEAD_COSTS` | beobachtet | offen |
| `PRCO_PRODUCTION_COSTS_ADJUSTMENTS` | beobachtet | offen |
Alle vorlaeufigen Beschreibungen sind ohne fachliche Freigabe nicht als Mapping-Entscheidung zu verwenden.
+82
View File
@@ -0,0 +1,82 @@
# Datenmodell
## Internes kanonisches Artikelmodell
Phase 0 definiert ein flaches Modell:
| Feld | Typ | Einheit | Status |
| --- | --- | --- | --- |
| `nr` | `str` | keine | Pflichtfeld |
| `name` | `str | null` | keine | optional |
| `width` | `float | null` | m | optional |
| `thickness` | `float | null` | mm | optional |
| `area_weight` | `float | null` | g/m2 | optional |
| `core_diameter` | `int | null` | mm | optional |
| `core_type` | `str | null` | keine | optional |
`nr` wird immer als String behandelt. Fuehrende Nullen bleiben erhalten.
## RollCalc-Ausgabemodell
Das geplante Ausgabemodell ist RollCalc-kompatibel und bleibt flach:
```json
{
"nr": "214700",
"name": "Stex H 751 (Tfix 751), 6,00 x 50 m",
"width": 6.0,
"thickness": 6.722,
"area_weight": 0.0,
"core_diameter": 100,
"core_type": "cardboard"
}
```
## Null-Werte und unbekannte Werte
Fehlende Werte sollen intern bevorzugt als `null` beziehungsweise `None` modelliert werden. Ob RollCalc `null`, fehlende Felder oder `0` erwartet, ist offen und darf nicht ohne dokumentierte Entscheidung geaendert werden.
Der Wert `0` darf nicht automatisch als unbekannt interpretiert werden. Im vorhandenen RollCalc-JSON treten `area_weight: 0.0` und `core_type: 0.0` auf. Die fachliche Bedeutung ist offen.
## Beobachtete RollCalc-JSON-Struktur
Lokale Datei: `incoming/article-data_.json`, nicht versioniert.
- 274 Artikel.
- Felder: `nr`, `name`, `thickness`, `area_weight`, `core_type`.
- `nr`: 274 Strings.
- `name`: 274 Strings.
- `thickness`: 273 Floats, 1 Integer.
- `area_weight`: 273 Floats, 1 Integer.
- `core_type`: 274 Floats.
- Mindestens eine Artikelnummer beginnt mit `0`.
## Herkunftsmetadaten
Spaeter koennen Herkunftsmetadaten pro Feld sinnvoll werden:
- Quelle
- Importzeitpunkt
- Originalfeld
- Originalwert
- Normalisierungsregel
- manueller Freigabestatus
Diese Metadaten gehoeren nicht zwingend in die RollCalc-Ausgabedatei.
## Offene fachliche Fragen
- Welche ERP-Spalte enthaelt eindeutig die fuer RollCalc relevante Produktbreite?
- Ist die ERP-Breite Nennbreite, Produktionsbreite oder Verkaufsbreite?
- Welche Einheit verwendet die ERP-Spalte?
- Koennen Artikelnummern im ERP mehrfach vorkommen?
- Falls ja: aus welchem fachlichen Grund?
- Welcher ERP-Datensatz ist bei Mehrfachtreffern massgeblich?
- Welche Bedeutung hat das bisherige Feld `core_type` mit numerischen Werten?
- Soll `core_type` kuenftig Textwerte oder Codes verwenden?
- Darf `0.0` bei `area_weight`, `thickness` oder `core_type` als unbekannt interpretiert werden?
- Welche Felder benoetigt RollCalc zwingend?
- Unterstuetzt RollCalc `null`?
- Soll der Artikelname aus dem ERP uebernommen oder nur zum Abgleich verwendet werden?
- Welche manuellen Felder duerfen ERP-Werte ueberschreiben?
- Wie wird die Qualitaet oder Freigabe manueller Daten gekennzeichnet?
+29
View File
@@ -0,0 +1,29 @@
# Entwicklung
## Voraussetzungen
- Python 3.12 oder neuer
- lokale virtuelle Umgebung
## Setup
```bash
python3 -m venv .venv
. .venv/bin/activate
python -m pip install -e ".[dev]"
```
## Checks
```bash
ruff check .
pytest
```
## Phase-0-Grenzen
Phase 0 enthaelt keine vollstaendige Merge-Implementierung und keine Weboberflaeche. Erlaubt sind kleine Interfaces, Tests und Hilfsfunktionen, die die geplante Architektur absichern.
## Abhaengigkeiten
Die Standardbibliothek wird bevorzugt. Neue Runtime-Abhaengigkeiten brauchen einen konkreten Nutzen und muessen in der Dokumentation nachvollziehbar sein.
+64
View File
@@ -0,0 +1,64 @@
# Merge-Regeln
## Matching
Primaerer Matching-Schluessel ist die Artikelnummer:
- RollCalc: `nr`
- ERP: beobachtet `SL_ITEM_NO`
- manuelle Daten: `nr`
Artikelnummern werden als Strings behandelt. Fuehrende Nullen bleiben erhalten. Normalisierung in Phase 0: nur fuehrende und nachgestellte Leerzeichen entfernen.
## Merge-Reihenfolge
1. ERP-Stammdaten
2. bestehende RollCalc-Berechnungsdaten
3. manuelle Ergaenzungen und explizite Korrekturen
Diese Reihenfolge ist eine Prioritaetsregel, aber keine Erlaubnis fuer stille Konfliktbereinigung.
## Mehrfache ERP-Treffer
Wenn dieselbe Artikelnummer mehrfach im ERP-Export vorkommt, darf Phase 1 keinen Datensatz stillschweigend auswaehlen. Der Artikel muss im Report erscheinen. Falls mehrere ERP-Zeilen fachlich gueltig sind, braucht es eine bestaetigte Auswahlregel.
## Fehlende Treffer
- Nur in RollCalc: Artikel bleibt als moeglicher Bestandsartikel sichtbar und wird reportet.
- Nur im ERP: Artikel wird als neuer oder nicht in RollCalc gepflegter Artikel reportet.
- Nur manuell: Artikel wird reportet, weil kein gesicherter Stammdatensatz vorhanden ist.
## Konflikte
Widerspruechliche Werte zwischen Quellen werden nicht stillschweigend ueberschrieben. Konflikte muessen mindestens Quelle, Artikelnummer, Feld, Quellwert und Zielwert enthalten.
## Feldprioritaeten
- ERP: Stammdaten, soweit Feld und Bedeutung bestaetigt sind.
- RollCalc: bestehende Berechnungsparameter wie `thickness`, `area_weight` und bisherige Kerninformationen.
- Manuell: Zusatzdaten und explizit freigegebene Overrides.
## Erlaubte manuelle Overrides
In Phase 0 vorgesehen:
- `core_diameter`
- `core_type`
- `area_weight`
Weitere Overrides muessen im Datenwoerterbuch dokumentiert werden.
## Reporting
Geplante Reports:
- `data/reports/merge-report.csv`
- `data/reports/unmatched-rollcalc-articles.csv`
- `data/reports/unmatched-erp-articles.csv`
- `data/reports/validation-report.json`
Reports koennen sensible Inhalte enthalten und werden nicht versioniert.
## Deterministische Ausgabe
Die exportierte JSON-Datei soll stabil sortiert werden, voraussichtlich nach normalisierter Artikelnummer. Das genaue Sortierverhalten wird in Phase 1 getestet.
+58
View File
@@ -0,0 +1,58 @@
# Roadmap
## Phase 0 - Repository und Datenverstaendnis
- Projektstruktur
- Dokumentation
- Beispieldaten
- Analyse der vorhandenen JSON- und CSV-Struktur
- Datenwoerterbuch
- Architekturentscheidungen
## Phase 1 - Reproduzierbarer CLI-Merge
- JSON-Importer
- ERP-CSV-Importer
- Import manueller CSV-Daten
- Normalisierung
- Validierung
- Merge
- Export der RollCalc-kompatiblen `article-data.json`
- Konflikt- und Trefferreports
- Unit- und Integrationstests
## Phase 2 - Qualitaetskontrolle
- Schema-Validierung
- Dublettenpruefung
- Einheitenpruefung
- Vergleich mit vorheriger Ausgabe
- Aenderungsreport
- Schutz vor unbeabsichtigtem Datenverlust
- Exit-Codes fuer Automatisierung
## Phase 3 - Einfache Pflegeoberflaeche
- lokale Weboberflaeche
- Suche nach Artikelnummer oder Name
- Anzeige der ERP-Werte
- Bearbeitung manueller Zusatzfelder
- Validierung bei Eingabe
- Aenderungsprotokoll
## Phase 4 - Erweiterte Datenhaltung
- SQLite als lokale Datenbasis
- Importhistorie
- Datenherkunft
- Aenderungsverfolgung
- Freigabestatus
- Benutzer- und Rollenmodell nur bei tatsaechlichem Bedarf
## Phase 5 - Integration
- definierter Export fuer RollCalc
- optionales Release-Artefakt
- optionaler automatisierter Import im RollCalc-Deployment
- Schnittstelle zu weiteren internen Werkzeugen
- moegliche Nutzung als Datenbasis fuer ein spaeteres Produktionsexpertensystem
+23
View File
@@ -0,0 +1,23 @@
# Sicherheit und Datenschutz
ERP-Daten koennen interne oder vertrauliche Inhalte enthalten. Produktive Exporte sollen nicht standardmaessig versioniert werden.
## Regeln
- `incoming/` ist nicht versioniert.
- `data/source/`, `data/manual/`, `data/generated/` und `data/reports/` sind fuer echte Arbeitsdaten ausgeschlossen.
- Beispieldaten muessen anonymisiert oder reduziert sein.
- Logs und Reports koennen Artikeltexte, Kosten, Produktionsdaten oder Konflikte enthalten und sind ebenfalls sensibel.
- Es ist keine Cloud-Abhaengigkeit erforderlich.
- Das Projekt soll lokal ausfuehrbar bleiben.
## Praktische Hinweise
Vor jedem Commit:
```bash
git status
git diff --cached
```
Keine produktiven ERP- oder RollCalc-Exporte nach `examples/` oder `tests/fixtures/` kopieren.