--- 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*