[ 'driver' => 'sqlite', 'database' => ':memory:', 'prefix' => '', 'foreign_key_constraints' => true, ], 'upstream_mirrors.connection' => 'business_mirror', ]); DB::purge('business_mirror'); $schema = DB::connection('business_mirror')->getSchemaBuilder(); $schema->create('business_mirror_sync_states', function (Blueprint $table): void { $table->string('dataset_key')->primary(); $table->string('source_key')->nullable(); $table->string('source_object')->nullable(); $table->string('status')->nullable(); $table->string('run_mode')->nullable(); $table->string('window_started_at')->nullable(); $table->string('window_ends_at')->nullable(); $table->string('cursor_completed_at')->nullable(); $table->string('cursor_business_id')->nullable(); $table->string('cursor_product_code')->nullable(); $table->dateTime('initial_completed_at')->nullable(); $table->dateTime('last_attempted_at')->nullable(); $table->dateTime('last_succeeded_at')->nullable(); $table->unsignedBigInteger('last_upserted_rows')->default(0); $table->string('last_error_code')->nullable(); $table->timestamps(); }); $schema->create('product_price_mirror_rows', function (Blueprint $table): void { $table->id(); $table->string('upstream_key')->unique(); $table->string('barcode'); $table->string('spu')->nullable(); $table->text('product_name')->nullable(); $table->string('category')->nullable(); $table->string('production_status')->nullable(); $table->decimal('minimum_price')->nullable(); $table->decimal('price_limit')->nullable(); $table->decimal('purchase_price')->nullable(); $table->decimal('shipping_fee')->nullable(); $table->decimal('jingxi_limit_price')->nullable(); $table->string('approval_status')->nullable(); $table->string('approval_result')->nullable(); $table->text('workflow_title')->nullable(); $table->dateTime('completed_at'); $table->string('business_id'); $table->string('row_hash'); $table->dateTime('synced_at'); $table->timestamps(); }); } public function test_page_two_and_literal_wildcard_filter_are_read_from_shared_mirror(): void { DB::connection('business_mirror')->table('business_mirror_sync_states')->insert([ 'dataset_key' => ProductPriceMirrorRepository::DATASET_KEY, 'initial_completed_at' => '2026-08-14 10:00:00', ]); foreach (range(1, 30) as $index) { DB::connection('business_mirror')->table('product_price_mirror_rows')->insert([ 'barcode' => $index === 30 ? 'SKU%_LITERAL' : sprintf('SKU%03d', $index), 'business_id' => sprintf('B%03d', $index), 'completed_at' => sprintf('2026-08-%02d 10:00:00', min($index, 28)), 'upstream_key' => hash('sha256', (string) $index), 'row_hash' => hash('sha256', 'row-' . $index), 'synced_at' => '2026-08-14 10:00:00', ]); } $repository = app(ProductPriceMirrorRepository::class); $pageTwo = $repository->paginate([], 2, 25); $literal = $repository->paginate(['barcode' => '%_'], 1, 25); $this->assertTrue($repository->initialized()); $this->assertSame(30, $pageTwo->total()); $this->assertCount(5, $pageTwo->items()); $this->assertSame(1, $literal->total()); $this->assertSame('SKU%_LITERAL', $literal->items()[0]->barcode); } public function test_same_business_and_barcode_at_different_completion_times_are_preserved(): void { DB::connection('business_mirror')->table('business_mirror_sync_states')->insert([ 'dataset_key' => ProductPriceMirrorRepository::DATASET_KEY, 'initial_completed_at' => '2026-08-14 10:00:00', ]); $repository = app(ProductPriceMirrorRepository::class); $rows = [[ 'business_id' => 'B100', 'barcode' => 'SKU100', 'cursor_completed_at' => '2026-08-14T10:00:00.1234567', 'completed_at' => '2026-08-14 10:00:00.123456', ], [ 'business_id' => 'B100', 'barcode' => 'SKU100', 'cursor_completed_at' => '2026-08-14T11:00:00.1234567', 'completed_at' => '2026-08-14 11:00:00.123456', ]]; $repository->storeBatch($rows, [ 'completed_at' => '2026-08-14T11:00:00.1234567', 'business_id' => 'B100', 'barcode' => 'SKU100', ], 2); $this->assertSame(2, DB::connection('business_mirror')->table('product_price_mirror_rows')->count()); $state = $repository->state(); $this->assertSame('2026-08-14T11:00:00.1234567', $state['cursor_completed_at']); $this->assertSame(2, (int) $state['last_upserted_rows']); } }