Skip to content

Commit e6dd616

Browse files
Avatarsiaclaude
andcommitted
docs: document bucket-accumulating cursor and gated -1s offset
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
1 parent dbddc49 commit e6dd616

File tree

1 file changed

+20
-5
lines changed

1 file changed

+20
-5
lines changed

docs/plans/woocommerce-pagination-fix.md

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ und verlustfrei, ohne neue Plugin-Abhängigkeiten und ohne Wechsel der API-Versi
4141
| Persistenz-Feld | `shopexport.einstellungen_json``felder.letzter_import_timestamp` | Bestehende Struktur nutzen, keine DB-Migration. |
4242
| Timestamp-Format | ISO-8601 `Y-m-d\TH:i:s` (UTC) | Direkt an `after=` durchreichbar. |
4343
| Caller-Cap (pre-existing) | `shopexport.maxmanuell`, default 100 | Der Batch-Cap liegt beim shopimport.php-Caller, nicht im Importer. |
44-
| Cursor-Format | Tupel `(letzter_import_timestamp, letzter_import_order_id)` | Loest Same-Second-Kollisionen via after=ts-1 + exclude=[id]. |
44+
| Cursor-Format | Tupel `(letzter_import_timestamp, letzter_import_order_ids: [int])` | IDs sammeln den aktuellen Sekunden-Bucket; -1s-Verschiebung greift nur mit mindestens einer ID. |
4545

4646
## 4. Datei- und Funktions-Landkarte
4747

@@ -144,16 +144,30 @@ SELECT einstellungen_json FROM shopexport WHERE id = <shopid>
144144
**Neu — Single-Order-Pseudocode:**
145145

146146
```
147-
afterTs = ts-1s (falls ts gesetzt)
148-
query = orders?after=<afterTs>&per_page=1&orderby=date&order=asc
149-
(+ exclude=[last_id] wenn last_id bekannt)
147+
# Fenster aufbauen
148+
if last_order_ids is not empty:
149+
after = last_ts - 1s
150+
exclude = last_order_ids
151+
else:
152+
after = last_ts
153+
exclude = (nicht gesetzt)
154+
155+
# Fetch
156+
order = client.get(orders, after=after, exclude=exclude, per_page=1, orderby=date, order=asc)[0]
150157
151158
if response is empty:
152159
return []
153160
154161
wcOrder = response[0]
155162
order = parseOrder(wcOrder)
156163
164+
# Persist
165+
if order.date_created_gmt == last_ts:
166+
last_order_ids = last_order_ids + [order.id]
167+
else:
168+
last_ts = order.date_created_gmt
169+
last_order_ids = [order.id]
170+
157171
persistLastImportCursor(order.date_created_gmt, order.id)
158172
159173
return [{ id: order.auftrag, sessionid: '', logdatei: '', warenkorb: ... }]
@@ -303,7 +317,8 @@ Manuelle Integrationstests mit seeded Test-Orders.
303317
| Andere Shopimporter erben Basisklasse-Struktur | niedrig | niedrig | Nur `shopimporter_woocommerce.php` anfassen, `ShopimporterBase` nicht anruehren |
304318
| URL-Laengenlimits der WAF beim `status[]`-Array | sehr niedrig | niedrig | Typisch 2-3 Status-Werte, URL bleibt kurz |
305319
| Caller-Kontrakt-Abweichung (1 vs. n Orders) | niedrig | hoch | Per Design Single-Order-Return; Caller-Loop fuer Volume-Handling |
306-
| Timestamp-Kollision bei identischem date_created_gmt | niedrig | mittel | Adressiert durch Tupel-Cursor (ts, id) + exclude-Parameter |
320+
| Timestamp-Kollision bei identischem date_created_gmt | niedrig | mittel | Adressiert durch Tupel-Cursor + Bucket-Akkumulation (letzter_import_order_ids sammelt alle IDs des Buckets) |
321+
| Unbounded exclude-Liste bei grossem Bucket | niedrig | niedrig | In der Praxis kleine Listen; URL < 2 KB bei ~100 IDs |
307322

308323
## 9. Definition of Done
309324

0 commit comments

Comments
 (0)