create(); $user = User::factory()->for($tenant)->create(); app(PdAuditLogger::class)->record( action: 'viewed', subjectType: 'lead', subjectId: 123, purpose: 'lead_card_view', tenantId: $tenant->id, actorTenantUserId: $user->id, actorAdminUserId: null, ip: '10.0.0.1', ); $row = DB::table('pd_processing_log')->latest('id')->first(); expect($row->action)->toBe('viewed') ->and($row->subject_type)->toBe('lead') ->and((int) $row->subject_id)->toBe(123) ->and((int) $row->actor_tenant_user_id)->toBe($user->id) ->and((string) $row->ip_address)->toBe('10.0.0.1'); }); it('allows system actor (both NULL) per chk_pd_actor', function () { $tenant = Tenant::factory()->create(); $before = DB::table('pd_processing_log')->count(); app(PdAuditLogger::class)->record( action: 'exported', subjectType: 'lead', subjectId: null, purpose: 'cron_cleanup', tenantId: $tenant->id, actorTenantUserId: null, actorAdminUserId: null, ip: null, ); expect(DB::table('pd_processing_log')->count())->toBe($before + 1); }); it('rejects two-actor row (chk_pd_actor violation)', function () { $tenant = Tenant::factory()->create(); $user = User::factory()->for($tenant)->create(); expect(fn () => app(PdAuditLogger::class)->record( action: 'viewed', subjectType: 'lead', subjectId: 1, purpose: 'x', tenantId: $tenant->id, actorTenantUserId: $user->id, actorAdminUserId: 999999, ip: null, ))->toThrow(QueryException::class); });