dojo: Plenty Cloud Tag-Manipulation + Silent-Deny-Diagnose
DOJO.md: - #22 (klassische variation_tags-Endpoints) ergänzt um Cloud-Update- Hinweis: in Plenty Cloud gesperrt, Verweis auf #34 - #33 NEU: Silent-Deny erkennen via Content-Type-Check (200+text/html als Erfolg melden ist die häufigste Lügen-Quelle bei Plenty-Schreib- Operationen) - #34 NEU: Variation-Tag-Manipulation in Plenty Cloud — Lese-Pfade, add-only PUT auf /rest/pim/variations für Hinzufügen, Bulk-DELETE /rest/pim/variations/tags für Entfernen; Plenty-Rollen-System hat keine Tag-Edit-Permission ANTI-PATTERNS.md: - #13 (Tag-Operationen idempotent) ergänzt um Cloud-Update-Hinweis - #19 NEU: Klassische /variation_tags-Endpoints in Plenty Cloud nutzen (Silent-Deny-Pattern, Verweis auf DOJO #34 als Fix)
This commit is contained in:
@@ -198,6 +198,8 @@ if (res.status !== 200) throw new Error('Tag konnte nicht gesetzt werden');
|
||||
|
||||
**Fix:** Diese HTTP-Codes als Erfolg behandeln, nicht als Fehler.
|
||||
|
||||
> **⚠ Update 2026-05-01 — Plenty Cloud:** In Plenty Cloud kommen 409/404 für Tag-Operationen auf `/variation_tags` gar nicht erst — der Endpoint ist gesperrt und antwortet mit Silent-Deny (siehe #19). Das hier dokumentierte Idempotenz-Pattern bleibt für On-Premise-Installationen gültig.
|
||||
|
||||
---
|
||||
|
||||
## 14. Neue Eigenschaften über den Merkmale-Endpoint setzen
|
||||
@@ -276,3 +278,33 @@ for (const item of items) {
|
||||
**Fix:** AIMD Rate Limiting: bei Erfolg schneller werden, bei 429 verdoppeln. Konvergiert automatisch zum Optimum. **Siehe DOJO.md #30**
|
||||
|
||||
---
|
||||
|
||||
## 19. Klassische `/variation_tags`-Endpoints in Plenty Cloud nutzen
|
||||
|
||||
```javascript
|
||||
// FALSCH: in Plenty Cloud Silent-Deny — schweigend ignoriert
|
||||
await client.delete(
|
||||
`/rest/items/${itemId}/variations/${vid}/variation_tags/${tagId}`,
|
||||
);
|
||||
// → 200 OK + Content-Type: text/html
|
||||
// → Tag bleibt aber an der Variation hängen
|
||||
```
|
||||
|
||||
**Problem:** Plenty Cloud hat die klassischen Tag-Manipulations-Endpoints für REST-User komplett gesperrt. Plenty antwortet mit der HTML-Login-Page (`x-location: /index.php`), nicht mit 401/403. Naive Clients erkennen das als Erfolg und melden falsch — der Tag bleibt in der Realität aber dran.
|
||||
|
||||
Plenty's Rollen-System bietet **keine eigene Tag-Edit-Permission** — der Endpoint ist nicht über User-Rollen freischaltbar. Stundenlange Permission-Recherche endet im Sackgassen-Modus.
|
||||
|
||||
**Fix:** PIM-Bulk-Endpoint nutzen + Content-Type prüfen. **Siehe DOJO.md #34**
|
||||
|
||||
```javascript
|
||||
// RICHTIG
|
||||
const resp = await client.delete('/rest/pim/variations/tags', {
|
||||
data: [{ variationId, tagId }],
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
});
|
||||
const ct = resp.headers?.['content-type']?.toLowerCase() ?? '';
|
||||
if (!ct.includes('application/json')) throw new Error('Silent-Deny');
|
||||
// + Verify-Read via /rest/pim/variations?with=tags.tag
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
@@ -523,6 +523,8 @@ DELETE /rest/items/{itemId}/variations/{variationId}/variation_tags/{tagId}
|
||||
- `404 Not Found` beim Löschen = Tag existiert nicht → ignorieren
|
||||
- Beides sind erwartete Zustände, keine Fehler
|
||||
|
||||
> **⚠ Update 2026-05-01 — Plenty Cloud:** Diese klassischen Endpoints sind in Plenty Cloud für REST-User **gesperrt** (Silent-Deny mit 200 + text/html). Tag-Manipulation läuft dort über die PIM-API — siehe **#34**. Die hier dokumentierten Endpoints können in älteren On-Premise-Installationen weiterhin funktionieren, in der Cloud aber nicht.
|
||||
|
||||
---
|
||||
|
||||
# IX. Cycle Times & KPIs
|
||||
@@ -903,3 +905,90 @@ await client.put(`/rest/properties/relations/${existing.id}`, {
|
||||
**Entdeckt:** 2026-04-10. Atradius-LimitMgmt. Wert nach PUT immer noch der alte.
|
||||
|
||||
---
|
||||
|
||||
## 33. Silent-Deny erkennen: Content-Type-Check bei Schreib-Operationen
|
||||
|
||||
**Lektion:** Plenty antwortet bei nicht-erlaubten Routen mit `200 OK + Content-Type: text/html + Header x-location: /index.php` (statt 401/403). Naive Clients, die nur den HTTP-Status prüfen, melden Erfolg, obwohl Plenty nichts geschrieben hat.
|
||||
|
||||
**Pattern:**
|
||||
```javascript
|
||||
const resp = await client.delete(url);
|
||||
const ct = String(resp.headers?.['content-type'] || '').toLowerCase();
|
||||
if (!ct.includes('application/json')) {
|
||||
throw new Error(
|
||||
'Plenty Silent-Deny: Antwort ohne JSON — vermutlich Permission-Problem ' +
|
||||
'oder Endpoint nicht für den API-User freigegeben.',
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
**Anti-Pattern:** Nur `resp.status === 200` prüfen — Plenty lügt freundlich:
|
||||
|
||||
```javascript
|
||||
// FALSCH: 200 OK reicht nicht
|
||||
await client.delete(url);
|
||||
return true; // ← lügt: Plenty hat HTML geliefert, nichts geändert
|
||||
```
|
||||
|
||||
**Diagnose-Tipps:**
|
||||
- `x-location: /index.php` als zusätzliches Indiz, aber **nicht verlässlich** — manche legitime Endpoints senden den Header auch
|
||||
- Body ist bei Silent-Deny meist leer
|
||||
- Verify-Read nach jeder Schreib-Operation ist die robusteste Variante
|
||||
|
||||
**Entdeckt:** 2026-05-01 bei Tag-DELETE-Operationen, die monatelang Erfolg meldeten ohne Tags zu entfernen. Erst Content-Type-Check + Verify-Read deckte den Lügenmodus auf.
|
||||
|
||||
---
|
||||
|
||||
## 34. Variation-Tag-Manipulation in Plenty Cloud: PIM-API + Bulk-DELETE-Endpoint
|
||||
|
||||
**Lektion:** Die klassischen Tag-Endpoints unter `/rest/items/{id}/variations/{vid}/variation_tags*` sind in Plenty Cloud für REST-User **komplett gesperrt** (Silent-Deny via #33). Der einzige funktionierende Schreib-Pfad führt über die PIM-API.
|
||||
|
||||
**Lese-Pfade** (beide funktionieren):
|
||||
```
|
||||
GET /rest/pim/variations?ids=in:{vid}&with=tags.tag
|
||||
GET /rest/items/{itemId}/variations/{vid}?with=tags
|
||||
```
|
||||
|
||||
Tag-Beziehungen kommen je nach Endpoint in unterschiedlichen Shapes — robuster Predicate:
|
||||
```javascript
|
||||
const matchesTag = (row, tagId) => {
|
||||
const candidates = [row.tagId, row.id, row.tag?.id, row.tag?.tagId];
|
||||
return candidates.some(v => Number(v) === tagId);
|
||||
};
|
||||
```
|
||||
|
||||
**Tag-Hinzufügen** — additive PUT auf der Variation (Plenty's eigenes Backend nutzt das):
|
||||
```
|
||||
PUT /rest/pim/variations?with=...&returnAffectedVariations=false
|
||||
Body: [{ id, base: {...}, tags: [...altList, {tagId: neuId}] }]
|
||||
```
|
||||
Wichtig: das `tags`-Array beim PUT ist **add-only**. Tags entfernen via Weglassen oder leeres Array funktioniert NICHT — `_destroy: true`-Marker auch nicht.
|
||||
|
||||
**Tag-Entfernen** — separater Bulk-Endpoint:
|
||||
```
|
||||
DELETE /rest/pim/variations/tags
|
||||
Content-Type: application/json
|
||||
Body: [{ "variationId": <vid>, "tagId": <tid> }, ...]
|
||||
← { "affectedRows": N }
|
||||
```
|
||||
|
||||
**Pattern:**
|
||||
```javascript
|
||||
const resp = await client.delete('/rest/pim/variations/tags', {
|
||||
data: items.map(i => ({ variationId: i.variationId, tagId: i.tagId })),
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
});
|
||||
const ct = String(resp.headers?.['content-type'] || '').toLowerCase();
|
||||
if (!ct.includes('application/json')) throw new Error('Plenty Silent-Deny');
|
||||
// `affectedRows` kann sporadisch 0 sein, obwohl Tag wirklich weg ist
|
||||
// → Verify-Read über GET ist verbindlich, nicht der affectedRows-Wert.
|
||||
```
|
||||
|
||||
**Permission-Hintergrund:**
|
||||
- Plenty's Rollen-System hat **keine Tag-Edit-Permission** (`tagShow.SHOW` ist die einzige Tag-Permission im ganzen Pool, kein `.EDIT/.DELETE`)
|
||||
- Der PIM-Bulk-Endpoint ist über die generische API-Rolle freigeschaltet, nicht route-spezifisch konfigurierbar
|
||||
- Wer eine Permission-UI sucht, sucht vergeblich — der Endpoint ist eine Plenty-interne Whitelist
|
||||
|
||||
**Entdeckt:** 2026-05-01 nach mehrstündiger Recherche. Korrekter Endpoint gefunden via Browser-Network-Capture des Plenty-Backends; Plenty's eigenes UI nutzt genau diesen Bulk-Pfad.
|
||||
|
||||
---
|
||||
|
||||
Reference in New Issue
Block a user