feat(apicore-sync): read from ApiCore's dedicated shop feed

The sync now fetches everything from ApiCore's GET /shop-sync in one call:
an allowlisted feed (harvest facts, article master data, bottlings) that
never contains internal notes and needs only the single permission
"shop-sync:read" instead of read access to harvests, extractions etc.

- Contract version is checked; an unknown version stops the run with a
  clear message and writes nothing. Extra fields are ignored.
- One consistent snapshot, processed only after it arrived completely: a
  failed fetch writes nothing (no more half state of new harvests and old
  batches); the batch-load-error path is gone.
- Falls back to the previous per-resource endpoints when ApiCore answers
  404, so both packages can be deployed independently.
- .env.example documents the reduced permission.

Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
This commit is contained in:
Nick SzaunigandClaude Opus 5.5 committed 2026-09-27 20:30:33 +02:00
1 parent d38f4303ff
commit 5642f0c4af
8 files changed
+224 -65

No files matched your search

+6 -6
View File
@@ -98,12 +98,12 @@ SMTP_FROM="Wabenhain <[email protected]>"
# separates Projekt (NestJS-Backend) mit reinem E-Mail/Passwort-Login (kein
# API-Key-Mechanismus) — hier IDEALERWEISE die Zugangsdaten eines
# dedizierten, MFA-freien Service-Kontos eintragen, nicht die eines echten
# Admin-Zugangs. Benoetigte Berechtigungen, alle nur lesend:
# harvests:read Ernten
# products:read Produktkatalog
# extractions:read Schleuderungen (verbinden Charge und Ernte)
# bottling:read Abfuellungen = Chargen
# apiaries:read optional, nur fuer die Standortnamen an den Ernten
# Admin-Zugangs. Benoetigte Berechtigung (in ApiCore unter Benutzer & Rollen
# eine eigene Rolle anlegen, die NUR diese eine Berechtigung hat):
# shop-sync:read freigegebene Shop-Daten (GET /shop-sync) — liefert nur
# Ernte-Fakten, Artikelstamm und Abfuellungen, keine Notizen
# Nur fuer aeltere ApiCore-Staende ohne /shop-sync (Rueckfall) noetig:
# harvests:read, products:read, extractions:read, bottling:read, apiaries:read
# Details siehe src/lib/apicore-client.ts.
APICORE_API_URL=
APICORE_SYNC_EMAIL=