بنقرة واحدة
data-migration-script
기존 Firestore 데이터 구조가 변경될 때 사용할 일회성 데이터를 일괄 백그라운드로 갱신하는 배치(Batch) 마이그레이션 스크립트 패턴
التثبيت باستخدام Codex أو Claude انسخ هذا Prompt والصقه في Codex أو Claude أو مساعد آخر ليراجع صفحة Skill ويثبّتها لك.
القائمة
기존 Firestore 데이터 구조가 변경될 때 사용할 일회성 데이터를 일괄 백그라운드로 갱신하는 배치(Batch) 마이그레이션 스크립트 패턴
التثبيت باستخدام Codex أو Claude انسخ هذا Prompt والصقه في Codex أو Claude أو مساعد آخر ليراجع صفحة Skill ويثبّتها لك.
استنادا إلى تصنيف SOC المهني
프로젝트 구조와 네이밍 컨벤션에 맞게 새 React 컴포넌트를 추가하는 가이드
PDF(인쇄 레이아웃) 및 Excel(xlsx 동적 로딩) 파일 내보내기 구현 및 갱신 패턴 가이드
Gemini 3.1 Flash Lite API를 사용한 계기판 OCR 및 증빙 서류 AI 판별 연동 패턴 가이드
Sentry에 잡힌 환경/브라우저/외부 의존성 발 노이즈 에러를 필터링한다. 사용자가 "Sentry 노이즈", "Sentry 에러 필터", "이 에러 무시", "Sentry에 자꾸 뜨는 X 막아줘" 등을 요청할 때 발동한다.
React 단위 테스트(Vitest) 및 E2E 테스트(Playwright) 작성 컨벤션과 Mocking 가이드
Cloud Functions, 프론트엔드 빌드 및 배포 시 발생하는 다양한 오류(Node 버전, 의존성 충돌, 소스맵)의 해결 패턴을 모아둔 가이드.
| name | data-migration-script |
| description | 기존 Firestore 데이터 구조가 변경될 때 사용할 일회성 데이터를 일괄 백그라운드로 갱신하는 배치(Batch) 마이그레이션 스크립트 패턴 |
Firestore 컬렉션의 스키마 필드가 변경되었거나, 기존 레거시 문서를 새로운 형식으로 모두 변환해야 할 때 이 패턴을 따릅니다. 수만 건 이상의 데이터를 처리하기 때문에 메모리를 초과하지 않도록 Pagination과 Batch Write가 필수입니다.
.agent/scripts/나 /scripts/ 경로 하위에 .ts 또는 .js 파일 형태로 생성합니다.firebase-admin 라이브러리를 사용하여 실행합니다.[!CAUTION] 프로덕션 DB를 다룰 때는 항상 1~2개 도큐먼트로 먼저 테스트하고 전체 배치를 실행하세요.
// scripts/migrate-legacy-logs.js
const admin = require("firebase-admin");
const serviceAccount = require("./service-account.json");
admin.initializeApp({
credential: admin.credential.cert(serviceAccount)
});
const db = admin.firestore();
async function migrate() {
const BATCH_SIZE = 500;
let hasNextPage = true;
let lastVisible = null;
let totalProcessed = 0;
while(hasNextPage) {
let query = db.collection('driveLogs').limit(BATCH_SIZE);
if (lastVisible) query = query.startAfter(lastVisible);
const snapshot = await query.get();
if (snapshot.empty) {
hasNextPage = false;
break;
}
const batch = db.batch();
snapshot.docs.forEach((doc) => {
const data = doc.data();
// 변환 규칙 적용
if (!data.newField) {
batch.update(doc.ref, { newField: "default_value" });
}
});
await batch.commit();
totalProcessed += snapshot.docs.length;
lastVisible = snapshot.docs[snapshot.docs.length - 1];
console.log(`Processed ${totalProcessed} documents...`);
}
console.log("Migration finished.");
}
migrate();