Initial import: Rechte/Pflichten/Regelwerk fuer Modul-Entwickler
This commit is contained in:
@@ -0,0 +1,44 @@
|
||||
# Getting Started
|
||||
|
||||
*(Quelle: neu, keine interne Vorlage)*
|
||||
|
||||
## Was ist ein HUBrobotix-Modul?
|
||||
|
||||
HUBrobotix.ai ist ein Core (Mandantensystem) + Module (Plugins), die über einen Marktplatz
|
||||
installiert werden. Ein Modul besteht aus:
|
||||
|
||||
- **Frontend** (HTML/JS unter `moduls/<dein_key>/{js,pages,modals}`)
|
||||
- **Eigenem Datenbank-Schema** (`db/schema.sql`, nur dein eigenes Schema, keine Core-Tabellen)
|
||||
- **Automations-Workflow** (n8n, deine eigentliche Server-Logik)
|
||||
- **`manifest.json`** (beschreibt dein Modul: Name, Version, benötigte Rechte, Einstiegspunkte)
|
||||
|
||||
## Grundregel Nummer 1
|
||||
|
||||
**Dein Modul-Code greift nie direkt auf eine Datenbank zu.** Jeder Datenzugriff läuft über die
|
||||
Core-API — auch auf dein eigenes Schema. Das ist keine Empfehlung, sondern technisch erzwungen:
|
||||
dein Modul-Code bekommt nie ein Datenbank-Passwort, egal wie du es baust. Details:
|
||||
[03-security-rules.md](03-security-rules.md).
|
||||
|
||||
## Ablauf in Kürze
|
||||
|
||||
```
|
||||
1. Lokal (dein Rechner, kein Zugang zu uns nötig):
|
||||
Frontend + manifest.json + db/schema.sql vorbereiten
|
||||
→ CLI-Tool (siehe SDK-Dokumentation) validiert lokal, kostenlos, sofort
|
||||
|
||||
2. Sandbox (unsere isolierte Test-Umgebung, Zugang nach Registrierung):
|
||||
Workflow bauen + testen mit Fake-Daten, echter KI-Testmodus möglich
|
||||
→ Details: 07-sandbox-usage.md
|
||||
|
||||
3. Einreichung (Developer-Portal):
|
||||
Paket hochladen → 5-stufige automatische Prüfung → menschliches Security-Audit
|
||||
→ Details: 06-submission-review-process.md
|
||||
|
||||
4. Marktplatz:
|
||||
Nach Freigabe: Modul ist im Marktplatz sichtbar, Mandanten können es installieren
|
||||
→ Details: 08-revenue-share.md (deine Vergütung)
|
||||
```
|
||||
|
||||
## Reihenfolge der weiteren Dokumente
|
||||
|
||||
Lies [01-manifest-schema.md](01-manifest-schema.md) als Nächstes.
|
||||
@@ -0,0 +1,86 @@
|
||||
# `manifest.json`-Schema
|
||||
|
||||
*(Quelle: `docs/core/module-requirements.md` §2/§3/§7, interne Details entfernt)*
|
||||
|
||||
Jedes Modul-Paket enthält genau eine `manifest.json` im Wurzelverzeichnis. Vollständiges Beispiel
|
||||
(am Beispiel eines fiktiven SPAM-Filter-Moduls):
|
||||
|
||||
```json
|
||||
{
|
||||
"module_key": "spam_filter",
|
||||
"module_name": "SPAM-Filter",
|
||||
"version": "1.0.0",
|
||||
"requires_core": ">=2.0",
|
||||
"api_contract": "v1",
|
||||
"description": "KI-gestützte E-Mail-Klassifizierung für IMAP-Postfächer",
|
||||
"author": { "name": "Deine Firma", "contact": "dev@example.com" },
|
||||
|
||||
"db_schema": "mod_spam_filter",
|
||||
|
||||
"roles": {
|
||||
"sa_features": ["global_prompts", "system_limits", "module_stats"],
|
||||
"ma_features": ["tenant_config", "llm_override", "email_templates", "user_permissions"],
|
||||
"user_permission": "write",
|
||||
"optional_user_gates": [
|
||||
{ "key": "can_override_classification", "label": "Darf KI-Klassifizierungen manuell überschreiben", "default": true }
|
||||
]
|
||||
},
|
||||
|
||||
"llm_capable": true,
|
||||
"llm_prompt_keys": ["classify_email", "classify_batch"],
|
||||
"email_templates": ["spam_daily_digest", "spam_stuck_alert"],
|
||||
|
||||
"widgets": [
|
||||
{
|
||||
"id": "spam_pending_count", "type": "metric", "label": "Offene Klassifizierungen",
|
||||
"default_size": { "w": 1, "h": 1 }, "min_size": { "w": 1, "h": 1 }, "max_size": { "w": 2, "h": 2 },
|
||||
"roles": ["superadmin", "tenant_admin", "user"], "refresh_interval_seconds": 60,
|
||||
"click_navigates_to": "spam-filter", "entry": "moduls/spam-filter/widgets/pending-count.js"
|
||||
}
|
||||
],
|
||||
|
||||
"frontend": {
|
||||
"pages": {
|
||||
"superadmin": "moduls/spam-filter/pages/sa-config.html",
|
||||
"tenant_admin": "moduls/spam-filter/pages/ma-config.html",
|
||||
"user": "moduls/spam-filter/pages/user-view.html"
|
||||
},
|
||||
"nav_key": "spam-filter", "nav_label": "SPAM-Filter", "nav_icon": "🛡"
|
||||
},
|
||||
|
||||
"api_scopes": ["spam_filter.read", "spam_filter.write", "spam_filter.admin"],
|
||||
"external_hosts": [],
|
||||
|
||||
"n8n": {
|
||||
"topology": "dispatcher-worker",
|
||||
"workflows": [
|
||||
{ "id": "spam-filter-api", "type": "api", "file": "workflows/hubrobotix-spam-filter-api.json", "schedule": null },
|
||||
{ "id": "spam-filter-dispatcher", "type": "scheduler", "file": "workflows/hubrobotix-spam-filter-dispatcher.json", "schedule": "*/10 * * * *" },
|
||||
{ "id": "spam-filter-worker", "type": "worker", "file": "workflows/hubrobotix-spam-filter-worker.json", "schedule": null }
|
||||
]
|
||||
},
|
||||
|
||||
"install": { "migrations": ["db/schema.sql"], "seed_fake": "db/seed-fake.sql" },
|
||||
|
||||
"test_cases": [
|
||||
{
|
||||
"id": "tc_pending_count", "description": "Widget pending-count gibt positive Integer zurück",
|
||||
"endpoint": "/spam-filter/stats/pending-count", "method": "GET", "scope": "spam_filter.read",
|
||||
"expect": { "status": 200, "body.count": ">= 0" }
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
## Wichtigste Felder im Detail
|
||||
|
||||
- **`module_key`**: eindeutig, muss vor Einreichung im Developer-Portal reserviert werden.
|
||||
- **`api_scopes`**: die **vollständige** Liste der Core-API-Scopes, die dein Modul je nutzt — die
|
||||
Prüf-Pipeline testet, dass du nie mehr nutzt als hier deklariert (Scope-Enforcement-Test).
|
||||
- **`external_hosts`**: jeder externe Host (Drittanbieter-API), den dein Modul-Code je aufruft, muss
|
||||
hier stehen — deine Modul-Instanz darf sonst netzwerkseitig nichts außer die Core-API erreichen.
|
||||
- **`n8n.topology`**: `single` (ein Workflow), `dispatcher-worker` (zwei gekoppelte Workflows) oder
|
||||
`queue` (echter n8n-Queue-Mode, braucht besondere Sandbox-Konfiguration — vorher anfragen).
|
||||
- **`test_cases[]`**: Pflicht, mindestens ein Testfall — läuft automatisch in Prüf-Stufe 4.
|
||||
|
||||
Weiter mit [02-core-api-reference.md](02-core-api-reference.md).
|
||||
@@ -0,0 +1,51 @@
|
||||
# Core-API-Referenz für Module
|
||||
|
||||
*(Quelle: `docs/core/core-api-implementation-plan.md` §3a/§9, `docs/core/hubrobotix-manifest.md`
|
||||
Gesetz 1/2, interne Server-Details entfernt)*
|
||||
|
||||
## Grundprinzip
|
||||
|
||||
Dein Modul-Code hält **nie** ein Datenbank-Passwort — auch nicht für dein eigenes Schema. Jeder
|
||||
Datenzugriff läuft über HTTP-Aufrufe gegen die Core-API, authentifiziert mit einem
|
||||
**pro-Modul-scoped Token** (`Authorization: Bearer <token>` + `X-Module-Key: <dein_module_key>`).
|
||||
|
||||
## Zwei Endpunkt-Familien
|
||||
|
||||
### 1. `mod/data/*` — deine eigenen Tabellen
|
||||
|
||||
Eine generische, auf dein eigenes Schema (`mod_<dein_key>`) beschränkte Endpunkt-Familie für
|
||||
CRUD auf deinen eigenen Tabellen. Dein Token kann ausschließlich auf `mod_<dein_key>.*` zugreifen —
|
||||
selbst ein Bug in deinem Code kann nie eine fremde Tabelle erreichen (das ist keine reine
|
||||
Anwendungslogik-Prüfung, sondern serverseitig auf Datenbank-Rollen-Ebene erzwungen).
|
||||
|
||||
### 2. Freigegebene Querschnittsdienste
|
||||
|
||||
Für Funktionen, die dein Modul braucht, die aber Core-Daten betreffen (kein eigenes Schema):
|
||||
|
||||
| Endpunkt | Zweck |
|
||||
|---|---|
|
||||
| `auth/verify` | JWT-Verifikation eines eingeloggten Nutzers |
|
||||
| `llm/complete` | KI-Vervollständigung (Anthropic/OpenAI/Ollama je nach Mandanten-Konfiguration) |
|
||||
| `prompt/get` | Lädt einen deklarierten Prompt-Text (System-Standard oder Mandanten-Override) |
|
||||
| `authz/check` | Prüft Modul-Freischaltung + Nutzerrechte für den aktuellen Request |
|
||||
| `template/render` | Rendert ein E-Mail-Template mit Platzhaltern |
|
||||
| `email/send` | Versendet eine E-Mail über den zentralen SMTP-Dienst |
|
||||
| `log/write` | Schreibt einen strukturierten Log-Eintrag |
|
||||
|
||||
**Wichtig:** Für komplexere eigene Server-Logik (Joins, Transaktionen über mehrere eigene Tabellen,
|
||||
eigene Business-Regeln) gibt es **keinen** bespoken Custom-Endpunkt in der Core-API — diese Logik
|
||||
gehört in deinen eigenen Workflow/Dienst, der mehrere `mod/data/*`-Aufrufe kombiniert.
|
||||
|
||||
## Fehlerbehandlung
|
||||
|
||||
Jede Antwort mit HTTP-Status ≥ 400 enthält `{ "error": "<Nachricht>" }`. Statuscode 5xx zeigt einen
|
||||
internen Fehler an unsererseits (dein Modul sollte das nicht als Nutzerfehler behandeln), 4xx zeigt
|
||||
einen Fehler auf deiner Seite (falscher Scope, ungültige Parameter etc.).
|
||||
|
||||
## Contract-Versionierung
|
||||
|
||||
Die Core-API-Endpunkte stehen unter `/v1/...`. Dein `manifest.json` deklariert `"api_contract": "v1"`
|
||||
— ein zukünftiger `/v2`-Bruch wird rechtzeitig angekündigt und betrifft dich nur, wenn du selbst auf
|
||||
`v2` migrierst.
|
||||
|
||||
Weiter mit [03-security-rules.md](03-security-rules.md).
|
||||
@@ -0,0 +1,89 @@
|
||||
# Verbindliche Sicherheitsregeln für Module
|
||||
|
||||
*(Quelle: `docs/core/hubrobotix-manifest.md` Gesetz 1–4, `docs/core/security-checklist.md`,
|
||||
interne Vorfall-Referenzen entfernt)*
|
||||
|
||||
Diese Regeln sind **Prüf-Kriterium** in der automatisierten Pipeline (Stufe 3, statische
|
||||
Sicherheitsanalyse) — ein Verstoß führt zum automatischen Scheitern, unabhängig davon, ob er
|
||||
absichtlich oder versehentlich ist.
|
||||
|
||||
## 1. Kein direkter Datenbankzugriff — auch nicht auf dein eigenes Schema
|
||||
|
||||
Kein `pg`, `mysql2`, kein Connection-String, keine rohe SQL-Query irgendwo in deinem Code. Jeder
|
||||
Datenzugriff läuft über die Core-API (`02-core-api-reference.md`). Dein Modul hält nie ein
|
||||
Datenbank-Credential.
|
||||
|
||||
## 2. Nur die Core-API + deklarierte externe Hosts
|
||||
|
||||
Dein Modul-Code darf ausgehend **ausschließlich** die Core-API sowie die in `manifest.json`
|
||||
unter `external_hosts[]` explizit gelisteten Drittanbieter-Hosts erreichen. Das wird nicht nur
|
||||
geprüft, sondern zur Laufzeit netzwerkseitig erzwungen (deine Modul-Instanz hat schlicht keinen
|
||||
Netzwerkpfad zu irgendetwas anderem).
|
||||
|
||||
## 3. Keine hartcodierten Secrets
|
||||
|
||||
Kein API-Key, kein Passwort, kein Token im Quellcode oder in einer committeten Datei — Secrets
|
||||
kommen ausschließlich über named Credentials in deinem Workflow, die bei Installation automatisch
|
||||
gegen echte, scoped Tokens ausgetauscht werden.
|
||||
|
||||
## 4. XSS-Schutz
|
||||
|
||||
Jeder Datenbankwert (auch aus deinem eigenen Schema), der in `innerHTML` oder ein
|
||||
Template-Literal für HTML-Ausgabe eingesetzt wird, muss escaped werden (Standard-Escape-Funktion
|
||||
aus dem Frontend-Baustein-Kit, siehe UI-Guidelines).
|
||||
|
||||
## 5. Auth-Guard fail-closed
|
||||
|
||||
Jede API-Route deines Moduls muss den Nutzerkontext serverseitig selbst prüfen — nie nur im
|
||||
Frontend filtern. Nicht authentifizierte Requests werden abgelehnt, nicht stillschweigend
|
||||
durchgelassen.
|
||||
|
||||
## 6. Owner-/Tenant-Check bei ID-Operationen
|
||||
|
||||
Jede Operation, die eine ID entgegennimmt (Update/Delete/Get), muss zusätzlich prüfen, dass diese
|
||||
ID tatsächlich zum aufrufenden Mandanten gehört — nie nur auf die ID selbst vertrauen.
|
||||
|
||||
## 7. Keine Client-seitigen JS-Popups
|
||||
|
||||
Kein `alert()`/`confirm()`/`prompt()` — nutze das bereitgestellte Modal-/Overlay-Muster (UI-Kit,
|
||||
siehe `04-ui-design-guidelines.md`).
|
||||
|
||||
## 8. Kein Auth-/Session-Token in URL-Parametern
|
||||
|
||||
Token niemals als URL-Parameter (`?t=...`) übergeben — ausschließlich `sessionStorage`.
|
||||
URL-Parameter landen in Server-Zugriffslogs, Browser-History und Referrer-Headern und sind damit
|
||||
faktisch unverschlüsselt gespeichert, selbst wenn die Verbindung TLS nutzt.
|
||||
|
||||
## 9. Datenbankzugriffs-Funktionen nur über `SECURITY DEFINER` + explizites `GRANT`
|
||||
|
||||
Wenn dein Modul eigene SQL-Funktionen für Datenzugriffe anlegt (z.B. um Core-API-Endpunkte
|
||||
technisch zu implementieren), müssen diese als `SECURITY DEFINER` deklariert und dein Zugriff
|
||||
per `GRANT EXECUTE ... TO <deine_rolle>` explizit erteilt sein — nie ein direktes `SELECT`/
|
||||
`INSERT`/`UPDATE` auf eine Tabelle gewähren, auch nicht rein lesend. Das ist keine Stilfrage: ein
|
||||
direkter Tabellenzugriff wird von der Datenbank mit "permission denied" verweigert, selbst wenn
|
||||
dein Code inhaltlich korrekt ist.
|
||||
|
||||
## 10. Keine neuen externen Script-Abhängigkeiten ohne Absicherung
|
||||
|
||||
Neue CDN-Scripts entweder lokal in deinem eigenen Modul-Ordner ablegen ODER mit
|
||||
`integrity="sha384-..."` + `crossorigin="anonymous"` einbinden. Ohne das würde eine kompromittierte
|
||||
CDN-Quelle beliebigen Code im Browser jedes Nutzers ausführen, der dein Modul verwendet.
|
||||
|
||||
## 11. Meta-Robots-Pflicht für jede neue Seite
|
||||
|
||||
Jede neue, eigenständig aufrufbare HTML-Seite deines Moduls bekommt im `<head>`:
|
||||
```html
|
||||
<meta name="robots" content="noindex, nofollow, noarchive">
|
||||
```
|
||||
Ohne diesen Tag werden Seiten von Suchmaschinen und KI-Crawlern indexiert, auch wenn sie
|
||||
eigentlich nur intern/für eingeloggte Nutzer gedacht sind.
|
||||
|
||||
## Was passiert bei einem Fund
|
||||
|
||||
- **Statischer Scan (Stufe 3):** automatisches Scheitern mit konkretem Fundort im Prüfbericht.
|
||||
- **Laufzeit-Test (Stufe 4):** selbst wenn eine Regel im Code umgangen würde (Verschleierung),
|
||||
greift die Ausführungsisolation der Sandbox — ein Modul, das z.B. `require('pg')` versucht, hat
|
||||
schlicht keinen Netzwerkpfad zu einer echten Datenbank. Das ist die eigentliche Garantie, nicht
|
||||
der Scan allein.
|
||||
|
||||
Weiter mit [04-ui-design-guidelines.md](04-ui-design-guidelines.md).
|
||||
@@ -0,0 +1,31 @@
|
||||
# UI-Design-Vorgaben für Module
|
||||
|
||||
*(Quelle: `docs/core/ui-design-system.md` §0, gekürzt auf die für Module verbindlichen Regeln)*
|
||||
|
||||
Diese Regeln werden **automatisch geprüft** — Verstöße blockieren die Marktplatz-Aufnahme
|
||||
(Prüf-Stufe 2, Stil-Compliance).
|
||||
|
||||
| Regel | Erlaubt | Verboten |
|
||||
|---|---|---|
|
||||
| Buttons in der GUI | `btn btn-indigo`, `btn btn-red`, `btn btn-gray`, `btn btn-green` | `btn-primary` (Gradient, nur für Login/Reset reserviert) |
|
||||
| Native Dialoge | `showConfirmModal()`, eigene Modals | `alert()`, `confirm()`, `prompt()` |
|
||||
| HTML-Ausgabe von DB-Werten | `_esc(wert)` | Direktes `innerHTML = wert` |
|
||||
| Modul-CSS-Scope | Eigene Klassen mit Modul-Präfix (z.B. `.deinkey-`) | Überschreiben von Core-CSS-Klassen ohne Präfix |
|
||||
| Externe Scripts | Lokal unter `moduls/<dein_key>/js/lib/` **oder** mit SRI-Hash (`integrity`+`crossorigin`) | CDN-Script ohne `integrity`-Attribut |
|
||||
| Neue HTML-Seiten | `<meta name="robots" content="noindex, nofollow, noarchive">` im `<head>` | Fehlendes robots-Tag |
|
||||
|
||||
## Warum diese Vorgaben
|
||||
|
||||
- **`btn-primary` nur Login/Reset:** Damit ein Nutzer auf einen Blick sieht, ob er sich in einem
|
||||
authentifizierten Bereich befindet oder nicht — ein Gradient-Button in der eingeloggten GUI würde
|
||||
das verwischen.
|
||||
- **Kein `alert()`/`confirm()`:** Native Browser-Dialoge lassen sich nicht stylen, blockieren den
|
||||
gesamten Tab und passen nicht ins Gesamtbild — jedes Modul nutzt dasselbe Modal-System.
|
||||
- **`_esc()` Pflicht:** verhindert XSS über Datenbankfelder, die Sonderzeichen enthalten könnten
|
||||
(siehe auch `03-security-rules.md`).
|
||||
|
||||
Das vollständige Farb-/Komponenten-System (Buttons, Modals, Tabellen, Badges, Formulare) wird dir
|
||||
nach Sandbox-Zugang als Referenz-CSS bereitgestellt — für die reine Pflicht-Compliance oben
|
||||
genügen diese sechs Regeln.
|
||||
|
||||
Weiter mit [05-mockup-guideline.md](05-mockup-guideline.md).
|
||||
@@ -0,0 +1,28 @@
|
||||
# Pflicht-Klick-Dummy vor der technischen Umsetzung
|
||||
|
||||
*(Quelle: `docs/core/module-mockup-guideline.md`, gekürzt)*
|
||||
|
||||
Bevor du mit Datenmodell, Workflow oder Frontend-Code beginnst, brauchst du einen **HTML-Klick-Dummy**
|
||||
mit Demo-Daten — das ist Teil der Prüf-Pipeline (Stufe 1, Konsistenz), nicht optional.
|
||||
|
||||
```
|
||||
Konzept-Dokument → Klick-Dummy (Demo-Daten) → deine eigene Abnahme
|
||||
→ erst danach: Datenmodell-Migrationen → API-Workflow → Frontend-Code → Sandbox-Deploy
|
||||
```
|
||||
|
||||
**Warum:** Ein Layout-, Rollen- oder Prozessfehler ist im Dummy eine Minute Änderungsaufwand.
|
||||
Im fertigen Datenmodell + Workflow + Frontend ist derselbe Fehler eine Migration, mehrere
|
||||
Workflow-Nodes und ein Redeploy.
|
||||
|
||||
## Pflichtbestandteile
|
||||
|
||||
1. **CI-Treue** — exakte Übernahme der Design-Tokens aus [04-ui-design-guidelines.md](04-ui-design-guidelines.md),
|
||||
keine eigene Farbpalette „weil es nur ein Dummy ist".
|
||||
2. **Alle Rollen-Ansichten, nicht nur eine.** Dein Modul-Manifest deklariert, welche Rollen dein
|
||||
Modul bedient (`roles.sa_features`/`ma_features`/`user_permission`, siehe
|
||||
[01-manifest-schema.md](01-manifest-schema.md)) — der Dummy muss für **jede** davon eine echte
|
||||
Ansicht zeigen, nicht eine reduzierte Version derselben Seite.
|
||||
3. **Dashboard-Widget-Vorschau**, falls dein Modul Widgets deklariert (`widgets[]` im Manifest) —
|
||||
wie sie im Mandanten-Dashboard tatsächlich aussehen würden.
|
||||
|
||||
Weiter mit [06-submission-review-process.md](06-submission-review-process.md).
|
||||
@@ -0,0 +1,42 @@
|
||||
# Einreichung & Prüfprozess
|
||||
|
||||
*(Quelle: `docs/core/module-submission-review-concept.md` B/C, interne Reconciliation-/Kosten-Details gekürzt)*
|
||||
|
||||
## 5 automatisierte Prüfstufen + menschliches Audit
|
||||
|
||||
Nach dem Hochladen deines Pakets im Developer-Portal durchläuft es automatisch fünf Stufen —
|
||||
jede muss zu 100 % bestehen, sonst Abbruch mit Fehlerbericht, den du direkt im Portal siehst:
|
||||
|
||||
| Stufe | Prüft |
|
||||
|---|---|
|
||||
| **1 Konsistenz** | `manifest.json`-Schema vollständig, Migrationskette lückenlos, Workflow-Namen stimmen mit dem Manifest überein |
|
||||
| **2 Stil-Compliance** | verbotene Muster (`alert/confirm/prompt`, `.btn-primary`, fehlendes `_esc()`, Meta-Robots-Tag), siehe [04-ui-design-guidelines.md](04-ui-design-guidelines.md) |
|
||||
| **3 Statische Security** | Secrets-Scan, jedes SQL-Statement = automatisches Scheitern (kein Modul enthält SQL), unerlaubte externe Hosts, siehe [03-security-rules.md](03-security-rules.md) |
|
||||
| **4 Laufzeit-Test** | Installation in einer frischen, ephemeren Sandbox mit Fake-Daten: Install/Uninstall sauber, alle `test_cases` aus deinem Manifest laufen grün, Scope-Enforcement wird aktiv getestet |
|
||||
| **5 KI-Review** | Ein Sprachmodell liest deinen vollständigen Code (bei Updates: nur den Diff) und bewertet verdächtige Logik, Prompt-Qualität, Fehlerbehandlung |
|
||||
|
||||
**Danach:** ein menschliches Security-Audit (nie durch dieselbe Person, die dein Modul freigibt,
|
||||
wenn sie es selbst eingereicht hätte — Vier-Augen-Prinzip). Entscheidung: freigeben / ablehnen
|
||||
(mit Begründung) / Rückfrage an dich.
|
||||
|
||||
## Zugangs-Tokens — was du siehst und was nicht
|
||||
|
||||
| Token-Typ | Wer sieht ihn | Wann |
|
||||
|---|---|---|
|
||||
| **Sandbox-API-Key** | Du, einmalig im Developer-Portal angezeigt (danach nur ein Fingerprint zur Wiedererkennung) | automatisch bei deiner Freischaltung als Entwickler |
|
||||
| **LIVE-Modul-Token** | **Nie du.** Wird erst bei der ersten Installation deines Moduls durch einen Mandanten automatisch erzeugt und ausschließlich intern verwahrt | bei Installation |
|
||||
|
||||
Du entwickelst und testest ausschließlich gegen deinen Sandbox-Zugang — der Austausch gegen echte,
|
||||
produktive Tokens passiert vollautomatisch bei der Installation, ohne dass du je einen echten
|
||||
Token siehst oder anfassen musst.
|
||||
|
||||
## Ablauf im Überblick
|
||||
|
||||
```
|
||||
Registrierung → SA schaltet dich frei → Sandbox wird automatisch bereitgestellt
|
||||
→ Du entwickelst + testest (07-sandbox-usage.md) → Paket-Einreichung
|
||||
→ Stufe 1–5 (automatisch) → menschliches Audit → Freigabe → Marktplatz-Listing
|
||||
→ Mandant installiert → LIVE-Token wird automatisch erzeugt (siehst du nie)
|
||||
```
|
||||
|
||||
Weiter mit [07-sandbox-usage.md](07-sandbox-usage.md).
|
||||
@@ -0,0 +1,62 @@
|
||||
# Die Sandbox — deine Entwicklungs- und Testumgebung
|
||||
|
||||
*(Quelle: `docs/core/module-developer-sandbox-concept.md` §2–§9, interne LIVE-Infrastrukturdetails entfernt)*
|
||||
|
||||
## Was die Sandbox ist
|
||||
|
||||
Eine **komplett eigenständige, isolierte Umgebung**, die sich für dich wie die echte Core-API
|
||||
verhält, aber strukturell nichts mit unseren echten Kundendaten, echten Secrets oder der echten
|
||||
Datenbank zu tun hat. Ein Sandbox-Zugang funktioniert **nur** gegen die Sandbox — es gibt keinen
|
||||
Konfigurationsfehler, der dir versehentlich echten Zugriff verschafft, weil es dafür keinen
|
||||
Netzwerkpfad gibt.
|
||||
|
||||
- **Daten:** rein synthetisch (Fake-Mandanten, Fake-Postfächer, Beispiel-E-Mails).
|
||||
- **KI-Anbindung:** zwei Modi — ein deterministischer Stub (kostenlos, reproduzierbar, Standard)
|
||||
oder ein budgetierter Echt-LLM-Testmodus, wenn du die fachliche Qualität deiner
|
||||
Prompt-Anbindung prüfen willst (fester Kosten-/Rate-Limit-Deckel pro Account).
|
||||
- **E-Mail-Versand:** wird nur geloggt simuliert, es geht nie eine echte Mail raus.
|
||||
|
||||
## Wie du Zugang bekommst
|
||||
|
||||
Nach deiner Freischaltung (siehe [06-submission-review-process.md](06-submission-review-process.md))
|
||||
wird automatisch eine eigene, isolierte n8n-Instanz für dich bereitgestellt. Du bekommst:
|
||||
|
||||
- Ein **eigenes n8n-Login** (eigene URL, nur du siehst deine eigenen Workflows)
|
||||
- Einen **Sandbox-Core-API-Token** (bereits als Credential in deiner n8n-Instanz vorkonfiguriert)
|
||||
- Optional **SFTP-Zugang** zu deinem eigenen Workspace (Workflow-Exporte, Paket-Dateien)
|
||||
- Optional **direkten, read-only Datenbank-Zugriff** auf dein eigenes Fake-Schema — **nur für dich
|
||||
persönlich zum Nachschauen während der Entwicklung.** Dein Modul-*Code* nutzt diesen Zugang nie —
|
||||
er spricht auch in der Sandbox ausschließlich über die Core-API (`mod/data/*`), damit er in LIVE
|
||||
identisch funktioniert.
|
||||
|
||||
Alle Zugänge betreffen ausschließlich deine eigene, isolierte Umgebung — du siehst nie Workflows,
|
||||
Daten oder Dateien eines anderen Entwicklers.
|
||||
|
||||
## Was lokal geht, was zwingend in der Sandbox passieren muss
|
||||
|
||||
**Lokal, auf deinem eigenen Rechner** (siehe auch die SDK-Dokumentation):
|
||||
Frontend, `manifest.json`, `db/schema.sql`-Entwurf, lokale Validierung, lokaler Core-API-Mock.
|
||||
|
||||
**Zwingend in der Sandbox:**
|
||||
- Schema/Felder anlegen — du hast keine direkten Schreibrechte auf die Datenbank-Struktur, sondern
|
||||
löst über das Portal eine Migration deiner `db/schema.sql` aus, die geprüft und dann angewendet
|
||||
wird (nur dein eigenes Schema, keine Core-Tabellen).
|
||||
- Der eigentliche Automations-Workflow — gebaut, ausgeführt und debuggt direkt im n8n-Canvas
|
||||
deiner Sandbox-Instanz, mit echten Ausführungs-Logs.
|
||||
- Fachliche Prüfung deiner KI-Anbindung (Echt-LLM-Testmodus) — ein lokaler Mock kann nur prüfen,
|
||||
ob der Aufruf technisch funktioniert, nicht ob die Antwort inhaltlich sinnvoll ist.
|
||||
|
||||
Dein fertiger Workflow wird als JSON exportiert und in dein eigenes Git-Repository
|
||||
zurückgeführt — du verlierst also keine Versionskontrolle, nur der Bau-/Testvorgang selbst
|
||||
läuft zwingend in der Sandbox.
|
||||
|
||||
## Lifecycle deiner Sandbox
|
||||
|
||||
| Zustand | Zeitraum | Was passiert |
|
||||
|---|---|---|
|
||||
| Aktiv | solange du eingeloggt bist/arbeitest | voller Zugriff |
|
||||
| Inaktiv | > 7 Tage ohne Login | pausiert (Daten bleiben erhalten, startet beim nächsten Login neu) |
|
||||
| Lange inaktiv | > 30 Tage ohne Aktivität | Benachrichtigung: „wird in 7 Tagen gelöscht" |
|
||||
| Gelöscht | > 37 Tage komplett inaktiv | Sandbox-Daten entfernt, dein Portal-Konto bleibt bestehen |
|
||||
|
||||
Weiter mit [08-revenue-share.md](08-revenue-share.md).
|
||||
@@ -0,0 +1,48 @@
|
||||
# Vergütung für Dritt-Entwickler
|
||||
|
||||
*(Quelle: `docs/billing/concept.md` §1.4, gekürzt auf die für dich relevanten Fakten)*
|
||||
|
||||
## Grundmodell
|
||||
|
||||
```
|
||||
Mandant zahlt Nutzungsgebühr für dein Modul ──► Plattform
|
||||
Plattform zahlt dir monatlich einen Anteil davon ──► dich (Revenue-Share)
|
||||
```
|
||||
|
||||
**Bis zu 70 %** des verteilbaren Betrags gehen an dich — der genaue Satz wird bei der
|
||||
Modul-Freigabe vertraglich mit dir vereinbart. 70 % ist die Obergrenze und der Standardsatz; ein
|
||||
niedrigerer Satz kommt nur in begründeten Fällen vor (z.B. hoher Reseller-Anteil deiner
|
||||
Modul-Kunden, hoher Support-Aufwand unsererseits).
|
||||
|
||||
## Wie der verteilbare Betrag berechnet wird
|
||||
|
||||
```
|
||||
Netto-Umsatz deines Moduls (alle Mandanten, ein Monat)
|
||||
− Reseller-Provisionen (falls Mandanten über einen Reseller kommen)
|
||||
− Zahlungsgebühren
|
||||
− tatsächliche KI-Kosten für dein Modul (nur wenn wir das System-LLM stellen —
|
||||
nutzt ein Mandant sein eigenes LLM, entfällt dieser Abzug)
|
||||
= verteilbarer Betrag
|
||||
→ davon bis zu 70 % an dich
|
||||
```
|
||||
|
||||
**Warum KI-Kosten vor der Teilung abgezogen werden:** Wir tragen die tatsächlichen API-Kosten für
|
||||
das System-LLM. Ohne diesen Abzug könntest du an einem Modul verdienen, das uns pro Ausführung
|
||||
mehr kostet, als es einbringt — der Abzug macht die Teilung fair und belohnt effiziente Prompts.
|
||||
|
||||
## Verlustfall
|
||||
|
||||
Ist der verteilbare Betrag in einem Monat negativ (selten, z.B. bei sehr hohem Reseller-Anteil),
|
||||
wird das als Verlustvortrag gegen die Folgemonate desselben Moduls verrechnet — keine Auszahlung,
|
||||
bis der Vortrag abgetragen ist. Damit trägst du einen Teil des Verlustrisikos mit, behältst aber
|
||||
auch weiterhin den vollen Anreiz für effiziente, kostengünstige Prompts.
|
||||
|
||||
## Auszahlung
|
||||
|
||||
Monatliche Gutschrift, sichtbar in deiner Umsatzübersicht im Developer-Portal. Auszahlung ab einer
|
||||
Mindestschwelle von 50 € — darunter wird der Betrag auf den Folgemonat vorgetragen.
|
||||
|
||||
---
|
||||
|
||||
Weiter mit [09-agent-system-prompt.md](09-agent-system-prompt.md) — dem copy-fertigen
|
||||
System-Prompt für deinen Coding-Agenten. Zurück zum [Index](README.md).
|
||||
@@ -0,0 +1,117 @@
|
||||
# System-Prompt für deinen Coding-Agenten/dein LLM
|
||||
|
||||
*(Quelle: neu — konsolidiert aus 00–08 dieses Bündels sowie projektinternen Lehren aus der
|
||||
HUBrobotix-Kernentwicklung, interne Details entfernt)*
|
||||
|
||||
Kopiere den Block unten **vollständig** als System-Prompt/erste Instruktion in deinen
|
||||
Coding-Agenten (Claude Code, Cursor, o.ä.), bevor du an deinem Modul arbeitest. Er fasst alle
|
||||
Regeln zusammen, die dein Agent kennen muss, damit er sich richtig verhält — die Dateien 00–08
|
||||
bleiben die ausführliche Referenz, dieser Prompt ist die verdichtete Handlungsanweisung.
|
||||
|
||||
---
|
||||
|
||||
## PROMPT (ab hier kopieren)
|
||||
|
||||
Du entwickelst ein Modul für die HUBrobotix.ai-Plattform in einer isolierten Sandbox-Umgebung.
|
||||
Halte dich strikt an folgende Regeln. Bei Unsicherheit: frage nach, statt eine Regel zu umgehen.
|
||||
|
||||
### 1. Architektur-Grundgesetz
|
||||
|
||||
- Dein Modul-Code greift **nie** direkt auf eine Datenbank zu — kein `pg`/`mysql2`, kein
|
||||
Connection-String, keine rohe SQL-Query, auch nicht auf dein eigenes Schema. Jeder Datenzugriff
|
||||
läuft über die Core-API (`mod/data/*` + Querschnittsdienste, siehe `02-core-api-reference.md`).
|
||||
- Datenbank-**Zugriffsfunktionen** (falls du eigene SQL-Funktionen in deinem Schema anlegst) immer
|
||||
als `SECURITY DEFINER`-Funktion mit explizitem `GRANT EXECUTE` an deine gescopte Rolle — nie
|
||||
direkten Tabellenzugriff gewähren, auch nicht lesend. Ein direktes `SELECT`/`INSERT` auf eine
|
||||
Tabelle deines eigenen Schemas ohne diesen Umweg schlägt zur Laufzeit mit "permission denied"
|
||||
fehl (bewusst so erzwungen, kein Bug).
|
||||
- Dein Code darf ausgehend **ausschließlich** die Core-API sowie in `manifest.json` unter
|
||||
`external_hosts[]` deklarierte Drittanbieter-Hosts erreichen — alles andere hat schlicht keinen
|
||||
Netzwerkpfad.
|
||||
- Keine hartcodierten Secrets im Code oder in committeten Dateien — ausschließlich über Named
|
||||
Credentials, die bei Installation gegen echte, scoped Tokens ausgetauscht werden.
|
||||
|
||||
### 2. Sicherheit (Details: `03-security-rules.md`)
|
||||
|
||||
- Jeder Datenbankwert, der in `innerHTML`/ein Template-Literal für HTML-Ausgabe eingesetzt wird,
|
||||
muss escaped werden (Standard-Escape-Funktion aus dem UI-Kit) — sonst XSS über Sonderzeichen.
|
||||
- Jede API-Route prüft den Nutzerkontext **serverseitig selbst** — nie nur im Frontend filtern.
|
||||
Nicht authentifizierte Requests werden abgelehnt, nie stillschweigend durchgelassen
|
||||
(fail-closed).
|
||||
- Jede Operation mit einer ID (Update/Delete/Get) prüft zusätzlich, dass die ID tatsächlich zum
|
||||
aufrufenden Mandanten/Nutzer gehört — nie nur auf die ID selbst vertrauen.
|
||||
- Kein Auth-/Session-Token jemals als URL-Parameter — ausschließlich `sessionStorage`. URL-Parameter
|
||||
landen in Server-Logs, Browser-History und Referrer-Headern.
|
||||
- Keine neuen externen Script-Abhängigkeiten ohne Subresource-Integrity (`integrity="sha384-..."`)
|
||||
oder lokale Ablage — bei einer CDN-Kompromittierung sonst beliebiger Code im Nutzer-Browser.
|
||||
- Vor jedem destruktiven/irreversiblen Vorgang (Löschen, Zurücksetzen, Überschreiben) eine
|
||||
Bestätigung mit Passwort oder mehrstufiger Freigabe einbauen — nie eine komplette
|
||||
Entwicklung/Konfiguration durch einen einzelnen Klick unwiderruflich zerstören lassen.
|
||||
|
||||
### 3. UI/CI (Details: `04-ui-design-guidelines.md`)
|
||||
|
||||
- Ausschließlich das bereitgestellte HUBrobotix-CSS/Komponenten-Kit verwenden — keine neue
|
||||
CSS-Bibliothek, kein neues Farbschema, keine ad-hoc erfundene Palette "weil es nur ein Mockup/
|
||||
Prototyp ist".
|
||||
- Kein `alert()`/`confirm()`/`prompt()` — ausschließlich das bereitgestellte Modal-/Overlay-Muster.
|
||||
- Kein Gradient-Button-Stil innerhalb der eigentlichen Anwendung (nur für Login/Reset-artige
|
||||
Einstiegsseiten zulässig) — in der App immer Solid-Buttons.
|
||||
- Jede neue HTML-Seite bekommt `<meta name="robots" content="noindex, nofollow, noarchive">` im
|
||||
`<head>`.
|
||||
|
||||
### 4. n8n-Workflow-Fallstricke (aus echten Vorfällen gelernt — nicht theoretisch)
|
||||
|
||||
- `splitInBatches` + `executeWorkflow` + `waitForSubWorkflow: true`: gibt der aufgerufene
|
||||
Sub-Workflow 0 Items zurück (typisch, wenn dessen eigener `splitInBatches`-"done"-Ausgang
|
||||
nirgendwo hinführt), bricht die äußere Schleife nach dem ersten Batch **still** ab. Lass den
|
||||
Dispatcher direkt über alle Items loopen, keine zusätzliche Gruppierungs-/Sub-Workflow-Ebene
|
||||
dazwischen.
|
||||
- `splitInBatches` mit `batchSize > 1` + `executeWorkflow`: alle Items eines Batches landen in
|
||||
**einer** Sub-Execution, die typischerweise nur `$input.first()` verarbeitet — der Rest wird
|
||||
**still** ignoriert. `batchSize = 1`, wenn jedes Item einzeln verarbeitet werden soll.
|
||||
- `fetch()` ist in n8n-Code-Nodes (vm2-Sandbox) nicht verfügbar — immer `require('https')`
|
||||
verwenden.
|
||||
- n8n-Expressions verstehen nur `{{ ... }}`, keine Jinja/Liquid-`{% if %}`-Blöcke — bedingte Logik
|
||||
komplett als JS-Ternary in einem einzigen `{{ }}`-Ausdruck schreiben.
|
||||
- Jeder Workflow, der einen mutierbaren Status setzt (z.B. `processing`/`pending`), braucht einen
|
||||
Error-Handler-Node, der den Status im Fehlerfall zurückrollt — sonst bleiben Datensätze
|
||||
dauerhaft und unsichtbar in einem Zwischenzustand hängen.
|
||||
- IMAP-Operationen in Schleifen immer sequenziell (`for...of`), nie `Promise.all()` — IMAP-Server
|
||||
limitieren gleichzeitige Verbindungen, parallele Aufrufe lösen Rate-Limits/Verbindungsabbrüche aus.
|
||||
|
||||
### 5. Git & Session-Isolation (verbindlich)
|
||||
|
||||
- Jede Änderung wird sofort committet und gepusht — kein Batchen mehrerer Änderungen in einen
|
||||
stillen, ungetrackten Zustand.
|
||||
- Vor jedem Commit `git status`/`git diff --stat` prüfen: es dürfen **ausschließlich** deine
|
||||
eigenen, bewusst beabsichtigten Dateien gestaged sein. Niemals blind `git add -A`.
|
||||
- **Session-Geschlossenheit:** Jede Entwicklungssitzung ist in sich abgeschlossen. Übernimm nie
|
||||
automatisch Code, Dateien oder Zustand aus einer anderen (parallelen oder früheren) Sitzung in
|
||||
einen Commit oder in den installierten Mockup-Stand — auch nicht "hilfreich gemeint". Wenn eine
|
||||
andere Sitzung parallel am selben Repository arbeitet, behandle deren Änderungen als fremd: nicht
|
||||
committen, nicht überschreiben, nicht automatisch mergen ohne ausdrückliche Anweisung.
|
||||
- Bevor du an einer geteilten/produktiven Sandbox-Ressource (echte Testdaten, ein bereits
|
||||
installiertes Mockup) einen Schreibtest durchführst: erst den Originalzustand sichern (z.B. per
|
||||
Export/Snapshot), damit ein versehentliches Überschreiben rückgängig gemacht werden kann.
|
||||
- Halte dich an bestehende Code-Muster in diesem Repository (Benennungen, Fehlerbehandlung,
|
||||
Ordnerstruktur) statt neue Konventionen einzuführen — Konsistenz schlägt persönlichen Stil.
|
||||
|
||||
### 6. Testen & Sauberkeit
|
||||
|
||||
- Jede neue Funktion vor "fertig"-Meldung tatsächlich live testen (echter Aufruf, kein reines
|
||||
Code-Lesen) — insbesondere Datenbankfunktionen, da Berechtigungsfehler oft erst zur Laufzeit
|
||||
auftreten (siehe Punkt 1, `SECURITY DEFINER`).
|
||||
- Nach jedem Live-Test eigene Testdaten/-dateien wieder aufräumen — keine Test-Artefakte in
|
||||
geteilten Tabellen oder auf geteilten Servern zurücklassen.
|
||||
- Ein Mockup (siehe `05-mockup-guideline.md`) muss **vollständig eigenständig** sein, wenn es auf
|
||||
eine isolierte Umgebung installiert wird — keine absoluten Pfade zu Assets, die nur auf einem
|
||||
anderen Server existieren (CSS/Fonts/Bilder ggf. inline einbetten statt zu verlinken).
|
||||
|
||||
---
|
||||
|
||||
## Ende des Prompts
|
||||
|
||||
Bei Widerspruch zwischen diesem Prompt und den ausführlichen Dateien 00–08: die ausführlichen
|
||||
Dateien sind die Quelle der Wahrheit, dieser Prompt ist nur die verdichtete Zusammenfassung. Bei
|
||||
Unklarheiten wende dich über das Developer-Portal an den Plattform-Betreiber, statt eine Regel
|
||||
nach eigenem Ermessen zu interpretieren.
|
||||
@@ -0,0 +1,35 @@
|
||||
# HUBrobotix.ai — Modul-Developer-Dokumentation (Pflichtbündel)
|
||||
|
||||
Dieser Ordner ist die **einzige Dokumentensammlung, die an Dritt-Entwickler ausgegeben wird** —
|
||||
bewusst getrennt von `docs/core/`, das interne Infrastrukturdetails (Servernamen, IPs,
|
||||
Incident-Historie) enthält und **nicht** an Externe geht. Jede Datei hier ist eine sanitierte,
|
||||
entwicklerorientierte Ableitung aus einem oder mehreren internen Konzeptdokumenten — die Quelle
|
||||
ist jeweils am Kopf jeder Datei vermerkt, damit wir bei internen Änderungen wissen, welche
|
||||
externe Datei nachgezogen werden muss.
|
||||
|
||||
## Pflichtlektüre-Reihenfolge
|
||||
|
||||
Ein Entwickler, der ein Modul für HUBrobotix.ai bauen will, muss **alle zehn Dateien** in dieser
|
||||
Reihenfolge gelesen haben, bevor er ein Paket einreicht (Prüf-Stufe 1 setzt das implizit voraus).
|
||||
**Datei 9 (Agent-System-Prompt)** ist zusätzlich zum Lesen auch wörtlich in den eigenen
|
||||
Coding-Agenten zu kopieren, bevor mit der eigentlichen Entwicklung begonnen wird.
|
||||
|
||||
| # | Datei | Inhalt | Quelle (intern) |
|
||||
|---|---|---|---|
|
||||
| 1 | [00-getting-started.md](00-getting-started.md) | Überblick, erste Schritte, Ablauf in einem Bild | neu |
|
||||
| 2 | [01-manifest-schema.md](01-manifest-schema.md) | `manifest.json`-Schema, Pflichtfelder | `docs/core/module-requirements.md` |
|
||||
| 3 | [02-core-api-reference.md](02-core-api-reference.md) | `mod/data/*` + Querschnittsdienste, Scopes | `docs/core/core-api-implementation-plan.md` §3a/§9 |
|
||||
| 4 | [03-security-rules.md](03-security-rules.md) | Verbindliche Sicherheitsregeln für Module | `docs/core/hubrobotix-manifest.md` Gesetz 1–4, `security-checklist.md` |
|
||||
| 5 | [04-ui-design-guidelines.md](04-ui-design-guidelines.md) | Farb-/Komponenten-Vorgaben, verbotene Muster | `docs/core/ui-design-system.md` |
|
||||
| 6 | [05-mockup-guideline.md](05-mockup-guideline.md) | Pflicht-Klick-Dummy vor Implementierung | `docs/core/module-mockup-guideline.md` |
|
||||
| 7 | [06-submission-review-process.md](06-submission-review-process.md) | 5-stufige Prüf-Pipeline + menschliches Audit | `docs/core/module-submission-review-concept.md` |
|
||||
| 8 | [07-sandbox-usage.md](07-sandbox-usage.md) | Sandbox-Nutzung, Zugangskanäle | `docs/core/module-developer-sandbox-concept.md` §2–§9 (**nicht** §10 LIVE-Interna) |
|
||||
| 9 | [08-revenue-share.md](08-revenue-share.md) | Vergütungsmodell | `docs/billing/concept.md` §1.4 |
|
||||
| 10 | [09-agent-system-prompt.md](09-agent-system-prompt.md) | Copy-fertiger System-Prompt für den eigenen Coding-Agenten — konsolidiert 00–08 + n8n-Fallstricke + Git/Session-Isolation | neu (verdichtet aus 00–08 + interne Lehren) |
|
||||
|
||||
## Pflege-Regel
|
||||
|
||||
Bei jeder inhaltlichen Änderung an einem der internen Quelldokumente prüfen, ob die zugehörige
|
||||
Datei hier nachgezogen werden muss — dieser Ordner darf nicht stillschweigend veralten, während
|
||||
sich die internen Regeln weiterentwickeln. Kein internes Detail (Server-IPs, Incident-Namen,
|
||||
Personennamen, interne Tooling-Pfade wie `/opt/...`) darf in diesen Ordner gelangen.
|
||||
Reference in New Issue
Block a user