Files
orderPRO/.paul/phases/128-erli-orders-import/128-01-SUMMARY.md
Jacek Pyziak 2565d9b754 feat(128): erli orders import
Phase 128 complete:
- add Erli /inbox order import with safe mark-read ACK
- add cron/manual import controls and sync state tracking
- map Erli orders into orderPRO aggregates with mapper tests and docs
2026-05-15 23:54:22 +02:00

178 lines
8.9 KiB
Markdown

---
phase: 128-erli-orders-import
plan: 01
subsystem: settings, integrations, cron, api, database, testing
tags: [erli, marketplace, orders-import, inbox, cron, mapper, automation]
requires:
- phase: 127-erli-integration-foundation
provides: global Erli credentials, settings UI, API client base
- phase: 112-reimport-data-protection
provides: delta-only OrderImportRepository contract
- phase: 119-reimport-total-paid-protection
provides: total_paid protection on stable payment status
provides:
- Erli orders import via /inbox
- manual Erli import action
- erli_orders_import cron handler and schedule
- Erli order mapper to orderPRO aggregate
- safe inbox ACK after zero-failure batch
affects: [erli-status-sync, erli-shipments, erli-tracking, automations, statistics]
tech-stack:
added: []
patterns: [inbox-driven-marketplace-import, safe-ack-after-batch, source-specific-order-mapper]
key-files:
created:
- database/migrations/20260515_000115_add_erli_orders_import_schedule.sql
- src/Modules/Cron/ErliOrdersImportHandler.php
- src/Modules/Settings/ErliOrderMapper.php
- src/Modules/Settings/ErliOrderSyncStateRepository.php
- src/Modules/Settings/ErliOrdersSyncService.php
- tests/Unit/ErliOrderMapperTest.php
modified:
- src/Modules/Settings/ErliApiClient.php
- src/Modules/Settings/ErliIntegrationRepository.php
- src/Modules/Settings/ErliIntegrationController.php
- src/Modules/Cron/CronHandlerFactory.php
- resources/views/settings/erli.php
- routes/web.php
- DOCS/DB_SCHEMA.md
- DOCS/ARCHITECTURE.md
- DOCS/TECH_CHANGELOG.md
key-decisions:
- "Erli order import uses /inbox as primary event source."
- "POST /inbox/mark-read ACK runs only after a zero-failure batch."
- "Phase 128 uses fixed status defaults; configurable mappings are deferred to Phase 129."
patterns-established:
- "ErliOrdersSyncService is shared by cron and manual import."
- "ErliOrderMapper returns null for unsupported inbox messages."
duration: ~14min
started: 2026-05-15T23:32:00+02:00
completed: 2026-05-15T23:46:00+02:00
---
# Phase 128 Plan 01: Erli Orders Import Summary
Erli now imports order events from `/inbox` into the shared orderPRO order aggregate, with cron/manual entry points, state tracking, automation hooks, and safe Erli inbox acknowledgement after a clean batch.
## Performance
| Metric | Value |
|--------|-------|
| Duration | ~14min |
| Started | 2026-05-15T23:32:00+02:00 |
| Completed | 2026-05-15T23:46:00+02:00 |
| Tasks | 6 acceptance areas completed |
| Files modified | 24 |
## Acceptance Criteria Results
| Criterion | Status | Notes |
|-----------|--------|-------|
| AC-1: Import configuration and schedule | Pass | Added `orders_fetch_enabled`, `orders_fetch_start_date`, interval UI, idempotent cron seed `erli_orders_import`, and manual import route. |
| AC-2: Fetch Erli inbox and ACK safely | Pass | `ErliApiClient::fetchInbox()` reads `/inbox`; `markInboxRead()` posts to `/inbox/mark-read` only after zero failures. Endpoint contract confirmed against official Erli swagger. |
| AC-3: Cursor/state and failure handling | Pass | `ErliOrderSyncStateRepository` records cursor, last run/success/error; failed batches mark failure and skip ACK. |
| AC-4: Map Erli order payload to orderPRO aggregate | Pass | Mapper covers source identifiers, status/payment defaults, customer/delivery/invoice addresses, items, payments, notes, status history, and invoice detection. |
| AC-5: Reuse shared order import and automations | Pass | Sync uses `OrderImportRepository`, preserves delta-only behavior, emits `order.imported` on create and `payment.status_changed` on payment transitions. |
| AC-6: Tests and documentation | Pass with environment gaps | Mapper unit test file added; docs updated. PHPUnit and Sonar CLI were unavailable in this checkout. |
## Accomplishments
- Added Erli order import service using the same orderPRO aggregate path as Allegro/shopPRO.
- Added cron composition and a manual "import now" action in Erli settings.
- Added import-state persistence so batches are observable and ACK is not sent on partial failure.
- Added Erli mapper coverage for common order, payment, invoice and cancellation cases.
- Updated technical docs for DB schema, architecture and changelog.
## Verification Results
| Check | Result |
|-------|--------|
| `php -l` on all changed PHP/view/lang/test files | Pass |
| Runtime mapper smoke via inline PHP | Pass: `MAPPER_SMOKE_OK` |
| `vendor/bin/phpunit tests/Unit/ErliOrderMapperTest.php` | Not run: `vendor/bin/phpunit` missing in checkout |
| `git diff --check` | Pass, with existing CRLF warnings only |
| `sonar-scanner` | Not run: CLI unavailable in PATH |
| Live migration + manual Erli import | Pending operator smoke on local/production DB |
## Files Created/Modified
| File | Change | Purpose |
|------|--------|---------|
| `database/migrations/20260515_000115_add_erli_orders_import_schedule.sql` | Created | Add sync-state fields and seed `erli_orders_import` cron schedule. |
| `src/Modules/Cron/ErliOrdersImportHandler.php` | Created | Cron handler for Erli import batches. |
| `src/Modules/Settings/ErliOrderMapper.php` | Created | Convert Erli inbox order messages to orderPRO aggregate. |
| `src/Modules/Settings/ErliOrderSyncStateRepository.php` | Created | Persist import cursor, success and error state. |
| `src/Modules/Settings/ErliOrdersSyncService.php` | Created | Coordinate fetch, map, upsert, automation and ACK. |
| `tests/Unit/ErliOrderMapperTest.php` | Created | Unit tests for mapper status/payment/invoice cases. |
| `src/Modules/Settings/ErliApiClient.php` | Modified | Add `/inbox` fetch and `/inbox/mark-read` ACK. |
| `src/Modules/Settings/ErliIntegrationRepository.php` | Modified | Store import settings and expose active integration credentials. |
| `src/Modules/Settings/ErliIntegrationController.php` | Modified | Save import settings and run manual import. |
| `src/Modules/Cron/CronHandlerFactory.php` | Modified | Register `erli_orders_import`. |
| `resources/views/settings/erli.php` | Modified | Add import controls and manual import button. |
| `routes/web.php` | Modified | Wire service construction and manual import route. |
| `DOCS/DB_SCHEMA.md`, `DOCS/ARCHITECTURE.md`, `DOCS/TECH_CHANGELOG.md` | Modified | Document schema, flow and technical change. |
## Decisions Made
| Decision | Rationale | Impact |
|----------|-----------|--------|
| Use Erli `/inbox` as the primary import source | Inbox is event-driven and aligns with Erli's message processing model. | Phase 129+ can use the same event source for status-related updates. |
| ACK only after zero-failure batch | Prevents losing Erli messages when a partial batch fails locally. | Failed messages remain unread for retry. |
| Keep status mapping defaults fixed in Phase 128 | User chose recommendation; full configurable mapping belongs to Phase 129. | Import works now, status tuning remains explicit next scope. |
## Deviations from Plan
### Summary
| Type | Count | Impact |
|------|-------|--------|
| Auto-fixed/clarified | 1 | ACK endpoint confirmed and implemented during APPLY. |
| Scope additions | 0 | No extra product scope added. |
| Deferred | 3 | Environment/live verification only. |
### Auto-fixed Issues
**1. Erli ACK endpoint contract**
- **Found during:** API client implementation.
- **Issue:** Plan intentionally left ACK endpoint verification open.
- **Fix:** Confirmed official Erli swagger uses `POST /inbox/mark-read` with `lastMessageId` or `ids`; implemented `lastMessageId`.
- **Verification:** API client method and sync path reference checked; live ACK pending real credentials.
### Deferred Items
- Run `php bin/migrate.php` and enable Erli import in `/settings/integrations/erli`.
- Click `Importuj zamowienia teraz` and confirm `orders.source='erli'` plus no unread messages after clean ACK.
- Install/restore PHPUnit tooling and run `tests/Unit/ErliOrderMapperTest.php`; run Sonar when CLI is available.
## Issues Encountered
| Issue | Resolution |
|-------|------------|
| `vendor/bin/phpunit` missing | Documented as verification gap; mapper smoke run with PHP runtime. |
| `sonar-scanner` missing in PATH | Documented as required-skill gap in STATE. |
| Live Erli import not executable without operator DB/API setup | Added explicit follow-up in STATE. |
## Skill Audit
| Expected | Invoked | Notes |
|----------|---------|-------|
| `sonar-scanner` | Gap | CLI unavailable in PATH; gap documented in STATE. |
## Next Phase Readiness
**Ready:**
- Phase 129 can add configurable Erli pull/push status mapping on top of imported Erli order status fields.
- Cron/manual import flow and state cursor are in place.
- Payment transition and first-import automation hooks are aligned with existing orderPRO contracts.
**Concerns:**
- Real inbox payload variance may require mapper additions after live smoke.
- PHPUnit and Sonar need environment repair for full verification.
**Blockers:**
- None for planning Phase 129.
---
*Phase: 128-erli-orders-import, Plan: 01*
*Completed: 2026-05-15*