Flutter 앱 골격 · 5탭 네비게이션 · 로그인 화면 · Firestore 보안 규칙·인덱스

This commit is contained in:
Sn-Kinos
2026-08-10 01:02:03 +09:00
parent fbba4405c3
commit 233ef99837
113 changed files with 8549 additions and 2 deletions
@@ -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();
}