docs(feature-plan): Refine DokuWiki architecture - inverted include approach

- Changed from marker-based sync to inverted include architecture:
  - Odoo generates read-only main page with equipment data
  - Main page includes user-editable :doku subpage via Include Plugin
  - Clear separation: Odoo owns structure, users own documentation

- Two-page system per equipment:
  - ausruestung:bereich:maschine (Odoo-generated, read-only)
  - ausruestung:bereich:maschine:doku (user-editable)

- Generisches ACL-System (maintenance-free):
  - ausruestung:*:doku @werkstatt 2 (editable)
  - ausruestung:* @werkstatt 1 (read-only)
  - Works automatically for all equipment

- Simplified sync algorithm:
  - Odoo completely overwrites main page (no marker parsing)
  - User content protected on separate page
  - Include renders both seamlessly

- Added detailed Python code examples
- Documented ACL wildcard matching rules
- Added table showing permission resolution

Benefits:
- No risk of users deleting sync markers
- Users cannot accidentally break Odoo data
- Self-healing: Odoo always regenerates correct structure
- Scalable: Works for 1000+ equipment pages
This commit is contained in:
Matthias Lotz 2025-12-13 18:16:33 +01:00
parent 2eff81ce54
commit 00f33faebe

View File

@ -150,13 +150,15 @@ Dieses Modul integriert **DokuWiki** als Dokumentationssystem für Equipment.
## 5.1 Ziele
- Automatische Wiki-Seiten für jedes Equipment
- Strukturierte Dokumentation mit Templates
- **Unidirektionale Synchronisation** (Odoo → DokuWiki)
- Odoo = Master für strukturierte Daten (Name, Seriennummer, Bereich, Kategorie)
- DokuWiki = Master für Freitext-Dokumentation (Bedienungsanleitung, Tipps)
- Nur markierte Bereiche werden von Odoo überschrieben
- **Invertierte Include-Architektur**:
- Odoo generiert geschützte Hauptseite mit Equipment-Daten
- Hauptseite inkludiert User-Dokumentation via Include Plugin
- User editieren separate `:doku` Unterseite
- **Klare Datentrennung**:
- Odoo = Master für strukturierte Daten (Hauptseite, read-only für User)
- User = Master für Freitext-Dokumentation (`:doku` Unterseite, editierbar)
- **Generisches ACL-System**: Eine Regel für alle Equipment
- Versionierung durch DokuWiki eingebaut
- ACL: Odoo-Namespace nur für Odoo beschreibbar, für alle lesbar
## 5.2 Architektur
@ -170,66 +172,75 @@ DokuWiki API (wiki.putPage)
ausruestung:bereich:maschinenname
```
## 5.3 DokuWiki-Namespace-Struktur
## 5.3 DokuWiki-Seitenstruktur
**Zwei-Seiten-System pro Equipment:**
```
ausruestung:holzwerkstatt:formatkreissaege
ausruestung:lasercutter:epilog_fusion_m2
ausruestung:elektronik:loetstation_1
ausruestung:holzwerkstatt:formatkreissaege ← Hauptseite (Odoo generiert)
ausruestung:holzwerkstatt:formatkreissaege:doku ← Doku-Seite (User editieren)
ausruestung:lasercutter:epilog_fusion_m2 ← Hauptseite
ausruestung:lasercutter:epilog_fusion_m2:doku ← Doku-Seite
```
**Namespace-Regeln:**
- Hauptnamespace: `ausruestung:`
- Zweite Ebene: Bereich (ows_area_id)
- Dritte Ebene: Equipment-Name (normalisiert, lowercase, ohne Sonderzeichen)
- **Hauptseite**: `ausruestung:bereich:maschinenname`
- Bereich: ows_area_id (normalisiert, lowercase)
- Maschinenname: Equipment name (normalisiert, ohne Sonderzeichen)
- **Komplett Odoo-generiert**, User können nicht editieren
- **Doku-Seite**: `ausruestung:bereich:maschinenname:doku`
- **User editieren hier frei** (Anleitungen, Tipps, Bilder)
- Wird via Include in Hauptseite eingebunden
- User können weitere Unterseiten anlegen (`:doku:bilder`, `:doku:videos`)
## 5.4 Template-System
## 5.4 Hauptseiten-Template (Odoo-generiert)
Automatisch generierte Seiten mit **Sync-Markern** für geschützte Bereiche:
Odoo erstellt die komplette Hauptseite inklusive Include für User-Dokumentation:
```wiki
====== Formatkreissäge ======
<!-- ODOO_SYNC_START: Grunddaten -->
===== Grunddaten =====
* **Seriennummer:** FKS-2024-001
* **Bereich:** Holzwerkstatt
* **Kategorie:** 🔴 (Einweisung erforderlich)
* **Bereich:** [[ausruestung:holzwerkstatt|Holzwerkstatt]]
* **Kategorie:** 🔴 Kategorie 3 (Einweisung erforderlich)
* **Standort:** Schrank A, Regal 2
* **Hersteller:** Bosch
<!-- ODOO_SYNC_END: Grunddaten -->
<!-- ODOO_SYNC_START: Sicherheit -->
===== Sicherheit =====
* **Einweisungspflichtig:** Ja
* **Nutzungsprodukte:** Holzwerkstatt Nutzung
* **Einweisungsprodukte:** Einweisung Formatkreissäge
<!-- ODOO_SYNC_END: Sicherheit -->
===== Bedienung =====
**Dieser Bereich ist NICHT geschützt - User können frei editieren!**
1. Maschine einschalten
2. Werkstück anlegen
3. Anschlag einstellen
...
* **Nutzungsprodukte:**
* Holzwerkstatt Nutzung (5€/Tag)
* **Einweisungsprodukte:**
* Einweisung Formatkreissäge (einmalig 25€)
===== Wartung =====
Letzte Wartung: 01.12.2025
Nächste Wartung: [[maintenance:request:42|Wartungsauftrag #42]]
* **Letzte Wartung:** 01.12.2025
* **Nächste Wartung:** 01.06.2026
* **Wartungshistorie:** [[odoo:maintenance:request:42|Alle Wartungsaufträge]]
===== Tipps & Tricks =====
**Freitext-Bereich für Community-Wissen**
===== Dokumentation & Anleitungen =====
{{page>.:formatkreissaege:doku&noheader}}
- Für saubere Schnitte: Sägeblatt regelmäßig wechseln
- Bei Hartholz: Vorschub langsamer
...
[[.:formatkreissaege:doku|✏️ Dokumentation bearbeiten]]
```
**Sync-Verhalten:**
- Bereiche zwischen `<!-- ODOO_SYNC_START -->` und `<!-- ODOO_SYNC_END -->` werden bei Equipment-Änderung aktualisiert
- Alle anderen Bereiche bleiben unberührt
- DokuWiki-Versionierung behält alle Änderungen
**User-Doku-Seite** (`:doku`, User editieren hier):
```wiki
==== Bedienung ====
1. Hauptschalter einschalten
2. Sägeblatt-Drehzahl einstellen
3. Anschlag positionieren
...
==== Tipps & Tricks ====
- Bei Hartholz: Vorschub langsamer
- Sägeblatt nach 50h wechseln
==== Bilder ====
{{.:doku:bild1.jpg?300}}
```
## 5.5 Technische Umsetzung
@ -248,49 +259,107 @@ wiki.getAllPages() # Alle Seiten auflisten
**Odoo-Integration:**
- Neues Model: `ows.dokuwiki.config` (DokuWiki-URL, Credentials)
- Methode auf `maintenance.equipment`: `sync_to_dokuwiki()`
- Liest bestehende Wiki-Seite mit `wiki.getPage()`
- Parsed Sync-Marker (`<!-- ODOO_SYNC_START -->`)
- Aktualisiert nur markierte Abschnitte
- Schreibt zurück mit `wiki.putPage()`
- Automated Action: Bei Equipment-Änderung → Wiki aktualisieren
- Smart Button: "Wiki öffnen" → Link zur DokuWiki-Seite
**Sync-Algorithmus:**
**Sync-Algorithmus (vereinfacht!):**
```python
def _update_structured_sections(self, existing_content, new_data):
"""Ersetzt nur Bereiche zwischen ODOO_SYNC_START/END Markern"""
sections = {
'Grunddaten': self._generate_grunddaten(),
'Sicherheit': self._generate_sicherheit()
}
def sync_to_dokuwiki(self):
"""Generiert Hauptseite mit Include für User-Doku"""
# 1. Generiere Hauptseite komplett (Odoo hat volle Kontrolle)
content = self._generate_equipment_page()
for section_name, new_content in sections.items():
marker_start = f"<!-- ODOO_SYNC_START: {section_name} -->"
marker_end = f"<!-- ODOO_SYNC_END: {section_name} -->"
# Regex-basiertes Ersetzen nur innerhalb Marker
existing_content = re.sub(
f"{marker_start}.*?{marker_end}",
f"{marker_start}\n{new_content}\n{marker_end}",
existing_content,
flags=re.DOTALL
)
# 2. Füge Include für User-Doku hinzu
wiki_id = self._get_normalized_name()
content += "\n\n===== Dokumentation & Anleitungen =====\n"
content += f"{{{{page>.:{{wiki_id}}:doku&noheader}}}}\n\n"
content += f"[[.:{{wiki_id}}:doku|✏️ Dokumentation bearbeiten]]\n"
return existing_content
# 3. Schreibe Hauptseite (überschreibt komplett)
main_page = f"ausruestung:{self.ows_area_id.wiki_name}:{wiki_id}"
dokuwiki_client.putPage(main_page, content, "Odoo Auto-Sync")
# 4. Erstelle leere Doku-Seite falls nicht vorhanden
doku_page = f"{main_page}:doku"
if not dokuwiki_client.getPage(doku_page):
initial_doku = "==== Bedienung ====\n\n==== Tipps & Tricks ====\n"
dokuwiki_client.putPage(doku_page, initial_doku, "Initial")
def _generate_equipment_page(self):
"""Generiert komplette Hauptseite mit Equipment-Daten"""
return f"""====== {self.name} ======
===== Grunddaten =====
* **Seriennummer:** {self.serial_no or 'N/A'}
* **Bereich:** [[ausruestung:{self.ows_area_id.wiki_name}|{self.ows_area_id.name}]]
* **Kategorie:** {self._get_category_icon()} {self._get_category_label()}
* **Standort:** {self.location or 'N/A'}
* **Hersteller:** {self.partner_id.name or 'N/A'}
===== Sicherheit =====
* **Einweisungspflichtig:** {self._is_training_required()}
* **Nutzungsprodukte:**
{self._format_product_list(self.ows_product_ids)}
* **Einweisungsprodukte:**
{self._format_product_list(self.ows_training_ids)}
===== Wartung =====
* **Letzte Wartung:** {self.last_maintenance_date or 'N/A'}
* **Nächste Wartung:** {self.next_action_date or 'N/A'}
"""
```
## 5.6 Sicherheitsmechanismen
**Vorteile dieser Architektur:**
- ✅ Keine Sync-Marker nötig (Hauptseite wird komplett überschrieben)
- ✅ User können Odoo-Daten nicht versehentlich löschen
- ✅ User-Content ist komplett geschützt (separate Seite)
- ✅ Include funktioniert transparent (User sehen alles auf einer Seite)
- ✅ Wartungsfreies ACL-System
## 5.6 ACL-System (Generisch & Wartungsfrei)
**DokuWiki ACL-Regeln:**
**DokuWiki ACL:**
```
ausruestung:* @ALL 1 # Lesezugriff für alle
ausruestung:* @odoo 8 # Schreibzugriff nur für Odoo-User
# User-Doku-Seiten editierbar (spezifischere Regel zuerst!)
ausruestung:*:doku @werkstatt 2 # Editieren erlaubt
ausruestung:*:doku:* @werkstatt 2 # Auch Unterseiten (Bilder, Videos, etc.)
# Hauptseiten nur lesen
ausruestung:* @werkstatt 1 # Nur Lesezugriff
ausruestung:* @ALL 1 # Alle können lesen
# Odoo hat vollen Zugriff überall
ausruestung:* @odoo 8 # Voller Zugriff
ausruestung:*:doku @odoo 8 # Auch auf Doku-Seiten (für Initial-Erstellung)
```
**ACL-Level Bedeutung:**
- `1` = Lesen
- `2` = Bearbeiten
- `8` = Upload + Löschen
- `16` = Admin (alle Rechte)
**Wie es funktioniert:**
| Seite | User @werkstatt | User @odoo | Ergebnis |
|-------|-----------------|------------|----------|
| `ausruestung:holzwerkstatt:formatkreissaege` | Matched: `ausruestung:*` → 1 | Matched: `ausruestung:*` → 8 | User: Lesen, Odoo: Schreiben |
| `ausruestung:holzwerkstatt:formatkreissaege:doku` | Matched: `ausruestung:*:doku` → 2 | Matched: `ausruestung:*:doku` → 8 | User: Editieren, Odoo: Voll |
**Vorteile:**
- ✅ **Komplett generisch**: Gilt automatisch für alle Equipment
- ✅ **Wartungsfrei**: Kein manuelles ACL-Setup pro Equipment
- ✅ **Selbsterklärend**: User sehen sofort wo sie editieren können
- ✅ **Skalierbar**: Funktioniert auch für 1000+ Equipment-Seiten
**Odoo-Seite:**
- Credentials in System-Parameter oder ir.config_parameter
- Verschlüsselte Speicherung des API-Passworts
- Logging aller Wiki-Änderungen
- Credentials in `ir.config_parameter`:
- `dokuwiki.url` (z.B. `https://wiki.hobbyhimmel.de`)
- `dokuwiki.user` (z.B. `odoo`)
- `dokuwiki.password` (verschlüsselt gespeichert)
- XML-RPC über HTTPS
- Logging aller Wiki-Operationen in `mail.message`
## 5.7 Vorteile DokuWiki