85f8e9e7a0
- SyncSupplierProjectJob: replace stub with full implementation (tries=3, backoff=[15,60,300]s; resolvePlatforms uppercase B1/B2/B3; buildUniqueKey site/call→signal_identifier, sms B2→sender+keyword, B3→sender; column name via strtolower($platform) to match schema snake_case) - SupplierPortalClient: drop final modifier (Mockery testability); add ensureSupplierProject() idempotent lookup-or-create wrapper - Tests: 6 passing (site/call/sms-with-kw/sms-no-kw/exception/partial-failure); DI fix via dispatchJobSync() helper resolving mock from container; uppercase platform fixtures matching CHECK constraint B1/B2/B3; last_error column absent from schema — partial-failure test uses sync_status only - phpstan-baseline.neon: add $this->mock() Pest TestCase inference gaps Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>