종모

종모

Tech Lead · Fullstack Developer

Seoul, Korea

🔧 본업도 개발, 취미도 개발

💥 임베디드부터 소프트웨어까지 우당탕 삽질과 해결 일지

📝 현재 포스팅과 과거 프로젝트 시리즈 연재중

🏷️ Tags

1인 개발 1인개발 504 Timeout @Cron AI AI 자동화 API API 문서화 API 설계 API설계
ARM Admin Portal Aggregate Aggregation Anthropic Anthropic API Application Layer Application Service Astro AuthGuard Batch BigInt Bounded Context CICD CORS CSS 변수 Claude Claude Code CleanArchitecture Cloud Run Cloud SQL Cloud Scheduler CloudSQL Cloudflare Cloudflare Pages Content Bridge Controller CouchDB Cron Cumulative DAG DDD DI DTO DataProvider Date Dependency Injection Docker Domain Domain Layer Domain Modeling E-E-A-T E2E FE 표준 FK Fallback Firebase Hosting Framer Motion GA4 대안 GCP GitHub Actions Google Guard HTTPS Homebrew IntersectionObserver Invalid hook call JWT Jest KST Legacy 정리 LiveSync Logging MDX Mock Mock-first N+1 NestJS Nginx Obsidian OpenAPI OpenClaw Oracle Cloud PATCH PK전략 PLATFORM_ADMIN PRD Passport Pixi.js PostMessage PostgreSQL Prisma Problem QA QR RBAC REST REST API RTT React React Admin Refine RenderTexture Repository SEO SSL SSoT ScheduleModule Schema Design Seed Snapshot Soft Delete Swagger TOP Rank Tailwind CSS TransformInterceptor Turborepo TypeScript Umami Unity Use Case Vite Vuplex Wallet API WebGL WebView Winston WordPress Zod axios class-validator deletedAt enum in-memory filtering macOS pnpm prisma generate react-hook-form recursive CTE session-sync shadcn tmux useCustom whileInView zod 개발일지 거래 원장 공개 API 구조화 데이터 구현기 권한 권한설계 기술선택 단위 테스트 단일 쿼리 데이터모델링 도메인 모델 도메인 모델링 도메인 이벤트 도메인모델링 디버깅 API 디자인 토큰 런타임 에러 레이스 컨디션 리버스 프록시 리전 리팩토링 리포트 마이그레이션 마일스톤 멀티테넌시 멀티테넌트 메모 동기화 모노레포 모바일 앱 문서화 배치고사 배포 백엔드 백엔드설계 브릿지 블로그 SEO 비즈니스 로직 빌드 사이드프로젝트 생산성 서드파티 하네스 서버 기동 테스트 성능 최적화 성능최적화 셀프호스팅 스키마 스키마설계 스택 오버플로우 스펙변경 아키텍처 오케스트레이션 운영 도구 워크트리 웹 애널리틱스 유틸리티 의존성관리 의존성주입 인사이트 인증 인증인가 인프라 자동 배포 자동 승급 자동화 자연어 생성 재귀 호출 정책 변경 초대 토큰 캐시 쿼리 파라미터 타이머 타임존 테스트 토큰 인증 통합 통화 시스템 트러블슈팅 폼 유효성 검사 품질 평가 프록시 협업 프로토콜 회고

📝 최근 글

📚 NestJS + Refine 풀스택 트러블슈팅

교육과정 도메인 BE 완성과 같은 날 핫픽스 7 건 — NestJS @Cron 2 중 실행 묶음

교육과정 도메인 BE 완성 머지 직후 7 시간 안에 7 건 핫픽스가 묶여 배포된 하루를 정리한다. Class API 폴백 사슬·level displayName 11 곳·login response teacherId 까지는 기능 보완이었지만, 06:00 킥오프 배치가 2 중 실행되며 회원당 과제 2 개가 생성된 사고는 NestJS ScheduleModule.forRoot() 중복 등록의 고전 함정이었다. forRoot 단일화·배치 1.5 단계 만료 로직·Student Home 조회 가드 세 방어 층을 같은 머지에 묶어 1,502 줄 세션 로그가 끝났다.

NestJSPrismaScheduleModule
📚 NestJS + Refine 풀스택 트러블슈팅

교육과정 자동 승급의 늪 — 도메인 버그 3 건 트러블슈팅

그룹 교육과정에 *레벨 25* 를 지정해 둔 회원이 *배치고사 건너뛰기* 직후 *레벨 15* 로 배정된 사고. 표면 증상은 하나였지만 진짜 원인은 *Class 동기화 누락 / getEffectiveCurriculum 폴백 누락 / 배치고사 건너뛰기의 currentLevelId 폴백* 세 도메인 버그가 한 사슬을 이루고 있던 점이었다. 폴백 4 단으로 재정렬하고 자동 승급 메서드 두 개를 들여 *EXCELLENT 3 일 + Top 도달* 조건을 한 흐름에 묶은 A 톤 트러블슈팅을 정리한다.

NestJSPrismaDomain Modeling
📚 NestJS + Refine 풀스택 트러블슈팅

Soft Delete 구현 — deletedAt 한 컬럼이 닿은 27곳의 설계

NestJS + Prisma 프로젝트에서 Member·Class·Operator 세 도메인 모델에 deletedAt 한 컬럼을 도입하며 마주친 27곳의 쿼리 필터, 트랜잭션 dependent 정리, 로그인 차단, FE 다이얼로그 흐름까지 도메인 모델 표준의 구현기를 정리한다. delete-check + DELETE 두 단계 API와 Application Service 16곳 + Domain Repository 11곳의 필터 분포까지 한 흐름으로 묶었다.

NestJSPrismaSoft Delete
📚 NestJS + Refine 풀스택 트러블슈팅

react-hook-form + Zod 폼 표준 정착기

여러 운영 페이지와 외부 SPA 에 흩어진 폼 12 개가 각자 다른 검증·정규화·에러 표시 흐름을 갖고 있었다. zod 공용 스키마를 `lib/validations/` 에 모으고, react-hook-form + zodResolver + shadcn/ui Form 한 흐름으로 묶으면서 입력 정규화·필드 에러·BE 에러 매핑까지 한 줄의 표준으로 정착시킨 구현기.

Reactreact-hook-formzod
📚 NestJS + Refine 풀스택 트러블슈팅

연락처 포맷 통일 — 저장은 숫자만, 표시는 하이픈

한 고객사에서 연락처 010-1234-5678 을 입력하면 BE 400, 01012345678 을 입력하면 통과되는 비대칭이 보고됐다. DB 를 열어 보니 같은 컬럼에 *하이픈 포함* 과 *숫자만* 이 섞여 누적돼 있었다. 진짜 범인은 *저장 포맷·입력 포맷·표시 포맷 세 축의 표준이 어디에도 없었던 점* 이었다. BE `phone.util.ts` + DTO `@Transform/@Matches` + FE zod `transform/refine` + 마이그레이션 SQL 을 *한 머지에 묶어* BE·FE·DB 세 곳을 동시에 정규화한 트러블슈팅을 정리한다.

NestJSPrismazod
📚 NestJS + Refine 풀스택 트러블슈팅

주간 출석 KST 타임존 — 월요일이 사라진 트러블슈팅

Unity 주간 출석 API 가 운영 한 달 후 월요일 칸만 무작위로 비었다. DB 에는 COMPLETED 과제가 분명히 있는데 화면은 null 이었다. 진짜 범인은 `new Date('2026-03-09')` 가 ISO 8601 로 파싱되어 UTC 자정 (= KST 09:00 월) 으로 잡힌 점이었고, batch 가 KST 00:00 으로 고정한 scheduledAt 이 쿼리 범위 *직전 9 시간* 에 들어가 통째로 누락되고 있었다. KST 자정 명시 생성자로 두 줄을 갈아끼우고, ESLint 룰과 jest mocking 가드로 재발을 막은 트러블슈팅을 정리한다.

NestJSPrisma타임존

🔥 시리즈별 최신

📚 블로그 SEO 실험실

Google E-E-A-T를 개인 블로그에 실제로 적용하는 방법 — 공식 문서 기반 실전 가이드

Google E-E-A-T(경험, 전문성, 권위, 신뢰)를 개인 기술 블로그에 실제로 적용한 과정을 정리합니다. 품질 평가 가이드라인을 읽고, 환경 명시 박스·레퍼런스 박스·구조화 데이터·시리즈 구조를 도입하기까지 — 공식 문서에서 근거를 찾고 하나씩 적용한 기록입니다.

SEOE-E-A-TGoogle
📚 1인 인프라 구축기

Claude Max 플랜으로 API 호출하면 429가 뜨는 이유 — 인증 체계 5단계 완전 정리

Claude Max 플랜의 OAuth 토큰(sk-ant-oat)으로 Messages API를 직접 호출하면 429 Rate Limit이 뜹니다. Claude Code의 인증 우선순위 5단계, sk-ant-oat vs sk-ant-api 차이, 그리고 스크립트에서 Max 플랜을 활용하는 우회법을 실제 트러블슈팅 사례와 함께 정리합니다.

ClaudeClaude CodeAnthropic API
📚 NestJS 실전 트러블슈팅

prisma generate 누락 — 빌드는 되는데 런타임 에러가 나는 이유

NestJS + Prisma 프로젝트에서 schema.prisma에 새 필드를 추가한 뒤 prisma generate를 빠뜨리면, TypeScript 빌드는 as any 캐스팅 덕에 통과하지만 런타임에서 Prisma Client가 새 필드를 모른다. pnpm build와 prisma generate가 별개 명령인 구조적 함정, prebuild 훅으로 자동화하는 해결법, Docker와 CI에서 놓치지 않는 예방 전략을 실전 코드와 함께 정리한다.

NestJSPrismaprisma generate