con un clic
add-cloud-function
functions/src/ 디렉터리에 새 Cloud Function을 추가하고 index.ts에 등록하는 패턴 가이드
Instalar con Codex o Claude Copia este prompt, pégalo en Codex, Claude u otro asistente, y deja que revise la página de la skill y la instale por ti.
Menú
functions/src/ 디렉터리에 새 Cloud Function을 추가하고 index.ts에 등록하는 패턴 가이드
Instalar con Codex o Claude Copia este prompt, pégalo en Codex, Claude u otro asistente, y deja que revise la página de la skill y la instale por ti.
프로젝트 구조와 네이밍 컨벤션에 맞게 새 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 | add-cloud-function |
| description | functions/src/ 디렉터리에 새 Cloud Function을 추가하고 index.ts에 등록하는 패턴 가이드 |
functions/
├── src/
│ ├── index.ts ← 엔트리 (모든 Cloud Function을 re-export)
│ ├── helpers.ts ← 공통 유틸 (severity 로깅, 에러 자동 래퍼)
│ ├── verifyHelpers.ts ← AI 문서 검증 및 OCR 관련 종합 복합 헬퍼
│ ├── constants.ts ← Remote Config 및 시스템 공통 상수
│ │
│ ├── ocrDashboard.ts ← onCall (계기판 사진 OCR 분석)
│ ├── ocrDocument.ts ← onCall / Helper (고유번호증 OCR 분석)
│ ├── autoVerifyDocument.ts ← Firestore 트리거 (기관 신청 시 AI 자동 증빙 검증)
│ ├── askAI.ts ← onCall (AI 질의 비서 응답 처리)
│ ├── generateFeedbackDraft.ts ← onCall (사용자 피드백 AI 답변 초안 자동 생성)
│ ├── regenerateFeedbackDraft.ts ← onCall (AI 답변 초안 재생성)
│ │
│ ├── createReservationSafe.ts ← onCall (동시성 중복 예약 차단 생성)
│ ├── sendAdminNotice.ts ← onCall (관리자 공지 및 전체 FCM 푸시 발송)
│ ├── sendAlimtalk.ts ← Helper (카카오 알림톡 전송 외부 API 연동)
│ ├── sendManualApprovalAlimtalk.ts← onCall (수동 승인/반려 알림톡 발송)
│ ├── sendNotification.ts ← Helper (FCM 알림 푸시 전송 핵심 모듈)
│ ├── notifyNewApplication.ts ← Firestore 트리거 (신규 신청서 등록 시 슈퍼관리자 알림)
│ ├── notifyRoleChange.ts ← Firestore 트리거 (유저 권한/역할 변경 알림)
│ ├── sendApprovalEmail.ts ← Helper (기관 신청 승인 메일 발송)
│ ├── sendRejectionEmail.ts ← Helper (기관 신청 반려 메일 발송)
│ ├── sendFeedbackReply.ts ← onCall (피드백 답변 완료 알림 발송)
│ │
│ ├── calendarSync.ts ← Helper (Google Calendar 단방향/양방향 연동 헬퍼)
│ ├── calendarSchedule.ts ← Schedule (Google Calendar 10분 주기 역동기화)
│ ├── testCalendarAccess.ts ← onCall (캘린더 연동 디버깅 및 API 테스트)
│ ├── triggerOnDemandCalendarSync.ts← onCall (수동 즉시 캘린더 동기화 요청)
│ ├── reservationTriggers.ts ← Firestore 트리거 (예약 생성/수정/삭제 시 연동 처리)
│ ├── reservationReminder.ts ← Schedule (예약 시작 임박 리마인더 알림 배치)
│ │
│ ├── holidayProxy.ts ← HTTP (공공 휴일 Open API 프록시)
│ ├── tmapProxy.ts ← HTTP (Tmap API 경로/거리 계산 프록시)
│ ├── syncHolidays.ts ← Schedule (매년 공휴일 자동 동기화 배치)
│ ├── warmupOcr.ts ← Helper (OCR 웜업 — reservationReminder 스케줄러에 편승 호출)
│ │
│ ├── backupFirestore.ts ← Schedule (Firestore 스토리지 일일 백업 배치)
│ ├── dailyNightlyBatch.ts ← Schedule (야간 데이터 정리 및 백그라운드 통합 배치)
│ ├── cleanupDuplicateLogs.ts ← HTTP (중복 운행일지 검출 및 보정 자동화)
│ ├── syncDriveLogKm.ts ← HTTP / onCall (전체 운행일지 누적거리 오차 보정 동기화)
│ ├── updateDriveLogStats.ts ← Firestore 트리거 (운행일지 등록 시 통계 실시간 집계)
│ │
│ ├── disableUser.ts ← onCall (유저 계정 비활성화 처리)
│ ├── restoreUser.ts ← onCall (유저 계정 복원 처리)
│ ├── onUserDelete.ts ← Firestore 트리거 (유저 정보 영구 삭제 시 리소스 연쇄 정리)
│ ├── setCustomClaims.ts ← Firestore 트리거 (유저 Auth Claims 권한 실시간 동기화)
│ ├── joinOrganization.ts ← onCall (기관 초대 코드 서버사이드 검증 및 소속 승인)
│ ├── submitOrgApplication.ts ← onCall (신규 기관 가입 신청 양식 검증 제출)
│ ├── submitPublicFeedback.ts ← onCall (비로그인 사용자 피드백 접수 검증)
│ ├── trackFirstEmployee.ts ← Firestore 트리거 (최초 가입 직원 판별 및 관리자 알림)
│ │
│ ├── rateLimit.ts ← Helper (API 레이트 리밋 스로틀링 모듈)
│ ├── discord.ts ← Helper (디스코드 웹훅 알림 송신 유틸)
│ ├── discordScheduler.ts ← Schedule (디스코드 시스템 상태 주기 요약 리포트 배치)
│ ├── apiHealthCheck.ts ← onCall / HTTP (외부 API 모니터링 및 헬스 체크)
│ ├── sendInactiveOrgAlimtalkScheduled.ts← Schedule (장기 미사용 기관 리마인드 알림 배치)
│ │
│ ├── caching/ ← 캐싱 관련 서브 모듈
│ ├── scheduler/ ← 스케줄러 래퍼 및 설정 모듈
│ ├── scripts/ ← 서버 관리 및 마이그레이션 배치 스크립트
│ └── __tests__/ ← Cloud Functions 단위/통합 테스트
├── package.json ← Node 22, firebase-functions v6, TypeScript
└── tsconfig.json
// newFunction.ts
import { onCall, HttpsError } from "firebase-functions/v2/https";
import { getFirestore } from "firebase-admin/firestore";
const db = getFirestore();
export const myFunction = onCall(
{
region: "asia-northeast3",
// 필요 시: memory: "512MiB", timeoutSeconds: 60
},
async (request) => {
// 인증 확인
if (!request.auth) {
throw new HttpsError("unauthenticated", "로그인이 필요합니다.");
}
const { param1, param2 } = request.data;
try {
// 비즈니스 로직
return { success: true };
} catch (err: unknown) {
console.error("myFunction 실패:", (err as Error).message);
throw new HttpsError("internal", "처리에 실패했습니다.");
}
}
);
// newFunction.ts
import { onRequest } from "firebase-functions/v2/https";
import { wrapHttps } from "./helpers";
export const myFunction = onRequest(
{
region: "asia-northeast3",
cors: true,
},
wrapHttps("myFunction", async (req, res) => {
// 비즈니스 로직
res.json({ success: true });
})
);
// 방법 A: 모듈에서 직접 onSchedule 래핑
import { onSchedule } from "firebase-functions/v2/scheduler";
export const myScheduledFn = onSchedule(
{
schedule: "every 1 hours",
timeZone: "Asia/Seoul",
retryCount: 0,
},
async () => {
// 비즈니스 로직
}
);
// 방법 B: 로직 함수만 export, index.ts에서 onSchedule 래핑
export async function myScheduledLogic(): Promise<void> {
// 비즈니스 로직
}
import { onDocumentCreated } from "firebase-functions/v2/firestore";
export const onItemCreated = onDocumentCreated(
"collectionName/{docId}",
async (event) => {
const data = event.data?.data();
const docId = event.params.docId;
if (!data) return;
try {
// 비즈니스 로직
console.log("처리 완료:", docId);
} catch (err: unknown) {
console.error("처리 실패:", docId, (err as Error).message);
}
}
);
새 파일을 만들었으면 index.ts에서 re-export합니다:
// 섹션 주석으로 그룹핑
// 새 기능 이름
export { myFunction } from "./newFunction";
⚠️
index.ts에서 export하지 않으면 배포되지 않는다.
공통 유틸리티를 적극 활용한다:
import { log, wrapHttps, wrapHandler } from "./helpers";
// 구조화 로깅 (Cloud Logging severity 기반 필터링)
log("INFO", "myFunction", "처리 시작", { userId: "abc" });
log("ERROR", "myFunction", "실패", { stack: error.stack });
// HTTP 핸들러 에러 자동 래핑
wrapHttps("myFunction", async (req, res) => { ... });
// onCall/트리거 핸들러 에러 자동 래핑
wrapHandler("myFunction", async (...args) => { ... });
API 키 등은 functions/.env 파일에 추가합니다:
# functions/.env
MY_API_KEY=abcdef123456
코드에서 사용:
const apiKey = process.env.MY_API_KEY;
import/export 사용 (CommonJS 아님)asia-northeast3 (서울) 고정engines.node로 지정)index.ts에서 한 번만 initializeApp(). 개별 모듈에서는 getFirestore(), getAuth() 등만 호출catch (err: unknown) → (err as Error).message 패턴cors: true 옵션 사용# Functions만 배포 (/deploy-functions 워크플로우 사용)
firebase deploy --only functions
# 로그 확인 (/logs 워크플로우 사용)
firebase functions:log --limit 50
Basado en la clasificación ocupacional SOC