Flutter 앱 골격 · 5탭 네비게이션 · 로그인 화면 · Firestore 보안 규칙·인덱스
This commit is contained in:
@@ -0,0 +1,74 @@
|
||||
import { readFileSync } from 'node:fs';
|
||||
import {
|
||||
collection,
|
||||
getDocs,
|
||||
orderBy,
|
||||
query,
|
||||
where,
|
||||
} from 'firebase/firestore';
|
||||
import {
|
||||
createTestEnvironment,
|
||||
seedDocuments,
|
||||
} from '../support/environment.mjs';
|
||||
|
||||
const manifest = JSON.parse(
|
||||
readFileSync(new URL('../../firestore.indexes.json', import.meta.url), 'utf8'),
|
||||
);
|
||||
const deliberatelyMissingFields = [
|
||||
['fandomId', 'ASCENDING'],
|
||||
['visibility', 'ASCENDING'],
|
||||
['createdAt', 'DESCENDING'],
|
||||
['likeCount', 'DESCENDING'],
|
||||
];
|
||||
const hasDeliberatelyMissingIndex = manifest.indexes.some((index) => {
|
||||
if (index.collectionGroup !== 'posts' || index.fields.length !== deliberatelyMissingFields.length) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return deliberatelyMissingFields.every(
|
||||
([fieldPath, order], position) =>
|
||||
index.fields[position].fieldPath === fieldPath && index.fields[position].order === order,
|
||||
);
|
||||
});
|
||||
|
||||
if (hasDeliberatelyMissingIndex) {
|
||||
throw new Error('Probe precondition failed: deliberately missing composite index exists');
|
||||
}
|
||||
|
||||
console.log('INDEX MANIFEST CONTROL PASS: required 4-field posts composite index -> absent');
|
||||
|
||||
const testEnvironment = await createTestEnvironment();
|
||||
|
||||
try {
|
||||
await testEnvironment.clearFirestore();
|
||||
await seedDocuments(testEnvironment, {
|
||||
'posts/post-1': {
|
||||
fandomId: 'fandom-a',
|
||||
visibility: 'visible',
|
||||
createdAt: '2026-08-08T00:00:00Z',
|
||||
likeCount: 1,
|
||||
},
|
||||
'posts/post-2': {
|
||||
fandomId: 'fandom-a',
|
||||
visibility: 'visible',
|
||||
createdAt: '2026-08-08T01:00:00Z',
|
||||
likeCount: 2,
|
||||
},
|
||||
});
|
||||
|
||||
const firestore = testEnvironment.authenticatedContext('alice').firestore();
|
||||
const missingIndexQuery = query(
|
||||
collection(firestore, 'posts'),
|
||||
where('fandomId', '==', 'fandom-a'),
|
||||
where('visibility', '==', 'visible'),
|
||||
orderBy('createdAt', 'desc'),
|
||||
orderBy('likeCount', 'desc'),
|
||||
);
|
||||
const result = await getDocs(missingIndexQuery);
|
||||
|
||||
console.log(`EMULATOR MISSING-INDEX QUERY RESULT: allowed (${result.size} documents)`);
|
||||
console.log('INDEX VALIDATION VERDICT: unsupported — emulator does not enforce composite indexes');
|
||||
} finally {
|
||||
await testEnvironment.cleanup();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user