toBeTrue(); foreach ([ 'id', 'platform', 'signal_type', 'unique_key', 'supplier_external_id', 'current_limit', 'current_workdays', 'current_regions', 'sync_status', 'last_synced_at', 'inactive_since', 'created_at', 'updated_at', ] as $col) { expect(Schema::hasColumn('supplier_projects', $col))->toBeTrue(); } }); test('supplier_projects has unique constraint on (platform, unique_key, subject_code)', function () { // v8.26 (project-migration-redesign Plan 1): per-субъект экспорт — composite unique // расширен до (platform, unique_key, subject_code) NULLS NOT DISTINCT. Старый // 2-колоночный индекс supplier_projects_platform_unique_key_unique заменён. $idx = DB::selectOne( "SELECT indexdef FROM pg_indexes WHERE tablename = 'supplier_projects' AND indexname = 'supplier_projects_platform_key_subject_unique'" ); expect($idx)->not->toBeNull(); expect($idx->indexdef) ->toContain('UNIQUE') ->toContain('platform') ->toContain('unique_key') ->toContain('subject_code'); }); test('supplier_projects platform check constraint allows only B1, B2, B3', function () { $check = DB::selectOne( "SELECT pg_get_constraintdef(c.oid) AS def FROM pg_constraint c JOIN pg_class t ON c.conrelid = t.oid WHERE t.relname = 'supplier_projects' AND c.conname = 'chk_supplier_projects_platform'" ); expect($check)->not->toBeNull(); expect($check->def) ->toContain("'B1'") ->toContain("'B2'") ->toContain("'B3'"); }); test('supplier_projects sync_status check constraint', function () { $check = DB::selectOne( "SELECT pg_get_constraintdef(c.oid) AS def FROM pg_constraint c JOIN pg_class t ON c.conrelid = t.oid WHERE t.relname = 'supplier_projects' AND c.conname = 'chk_supplier_projects_sync_status'" ); expect($check)->not->toBeNull(); expect($check->def) ->toContain("'pending'") ->toContain("'ok'") ->toContain("'failed'"); }); test('supplier_projects has NO RLS policy (relrowsecurity = false)', function () { $row = DB::selectOne( "SELECT relrowsecurity FROM pg_class WHERE relname = 'supplier_projects' AND relkind = 'r'" ); expect($row)->not->toBeNull(); expect($row->relrowsecurity)->toBeFalse(); }); test('supplier_projects has REVOKE ALL on crm_app_user (no privileges in role_table_grants)', function () { $rows = DB::select( "SELECT privilege_type FROM information_schema.role_table_grants WHERE table_name = 'supplier_projects' AND grantee = 'crm_app_user'" ); expect($rows)->toBe([]); });