종모

종모

Tech Lead · Fullstack Developer

Seoul, Korea

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

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

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

🏷️ Tags

1인 개발 1인개발 504 Timeout 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 Cloudflare Cloudflare Pages Content Bridge Controller CouchDB Cron Cumulative DAG DDD DI DTO DataProvider Dependency Injection Docker Domain Domain Layer Domain Modeling E-E-A-T E2E FK Fallback Framer Motion GA4 대안 GitHub Actions Google Guard HTTPS Homebrew IntersectionObserver Invalid hook call JWT Jest 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 RBAC REST REST API React React Admin Refine RenderTexture Repository SEO SSL SSoT 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 shadcn tmux useCustom whileInView zod 개발일지 거래 원장 공개 API 구조화 데이터 권한 권한설계 기술선택 단위 테스트 단일 쿼리 데이터모델링 도메인 모델링 도메인 이벤트 도메인모델링 디버깅 API 디자인 토큰 런타임 에러 레이스 컨디션 리버스 프록시 리팩토링 리포트 마이그레이션 멀티테넌시 멀티테넌트 메모 동기화 모노레포 모바일 앱 문서화 배치고사 백엔드 백엔드설계 브릿지 블로그 SEO 비즈니스 로직 빌드 사이드프로젝트 생산성 서드파티 하네스 서버 기동 테스트 성능 최적화 성능최적화 셀프호스팅 스키마 스키마설계 스택 오버플로우 스펙변경 아키텍처 오케스트레이션 운영 도구 워크트리 웹 애널리틱스 유틸리티 의존성관리 의존성주입 인사이트 인증 인증인가 인프라 자동 배포 자동화 자연어 생성 재귀 호출 정책 변경 초대 토큰 캐시 쿼리 파라미터 타이머 테스트 토큰 인증 통합 통화 시스템 트러블슈팅 폼 유효성 검사 품질 평가 프록시 회고

📝 최근 글

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

외부 뷰어 리포트 4탭 N+1 — 14초 응답을 2초로

외부 뷰어 리포트 토큰 한 줄로 들어가는 공개 페이지의 4탭 단일 응답이 최대 14.4초까지 늘어났다. Prisma `include` 만 의심하다 진짜 범인을 놓쳤다. 두 층의 N+1 — 4탭 빌더 6 건의 순차 await + 일별·주별 for 루프 안 `findMany` 반복 — 을 Promise.all 병렬화 + 단일 findMany + 메모리 그룹핑으로 풀어 55 개 쿼리를 10 개로, p95 응답을 ~2.3 초로 끌어내린 트러블슈팅을 정리한다.

NestJSPrisma성능최적화
📚 NestJS + Refine 풀스택 트러블슈팅

Framer Motion whileInView — 일부 카드만 안 뜨던 날

외부 뷰어 리포트의 4탭에 인사이트 카드와 빈 데이터 폴백을 같이 깔고 나니 일부 motion.section의 whileInView 애니메이션이 트리거되지 않았다. 같은 컴포넌트가 같은 코드로 어떤 탭에서는 정상이고 어떤 탭에서는 opacity 0으로 그대로 멈췄다. 원인은 조건부 마운트 시점에 IntersectionObserver의 첫 콜백이 framer-motion 이펙트 부착 전에 끝나 버린 레이스 + viewport.once 기본값 false의 합이었다. once:true 표준화 + sentinel ref + ESLint 가드를 같이 깐 트러블슈팅을 정리한다.

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

외부 뷰어 리포트 인사이트 — 활동 데이터를 자연어로 바꾸기

외부 뷰어가 보는 4탭 리포트에 차트 옆으로 한 줄 자연어 메시지를 붙이는 인사이트 시스템 도입 머지를 정리한다. AI 호출 없이 결정성을 보장하는 룰 기반 메시지 생성기, 5 + 4 + 5 = 14종 긍정 규칙, 빈 데이터 폴백 카피 4종, 4탭별 메시지 슬롯 배치 — 같은 dev 머지 사이클 안에서 응답 표준 + 룰 + 폴백을 동시에 굳힌 설계 흐름과 트레이드오프를 기록한다.

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

외부 뷰어 리포트 v1→v2 토큰 전환 — 가장 길었던 하루

도입 단계 머지가 같은 날 밤 사용자 검토 1회로 폐기된 사고. Parent / ParentStudent / ParentInvitation 3 모델 + 회원가입 단일 트랜잭션 + 별도 JWT 시크릿 흐름 전부 삭제, StudentReport 1 모델 + nanoid 21자 공개 토큰 + 7일 만료 정책으로 같은 dev 머지 사이클 안에 갈아엎은 BE -2,099 / +563 + FE -1,475 / +968 의 갈아엎기 비용과 결정 사유, 사후 평가를 정리한다.

NestJSPrisma토큰 인증
📚 NestJS + Refine 풀스택 트러블슈팅

보호자 외부 뷰어 대시보드 — 모바일 앱·초대 토큰 회원가입

회원 레포트와 같은 데이터를 보호자(외부 뷰어) 그릇으로 옮기는 별도 앱 도입 머지. 모바일 우선 컨테이너(max-w-[430px]), Parent/ParentStudent/ParentInvitation 3 신규 모델, 초대 토큰 + 회원가입 단일 트랜잭션(4 write), 별도 JWT 시크릿(1h access / 30d refresh), 전화번호 = 로그인 ID 결정을 같은 dev 머지 사이클 4시간 안에 BE + FE Mock + FE 인증 연동까지 묶은 도입 단계 마일스톤이다.

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

회원 레포트 5탭 API 설계 — 인사이트 3파트 구조

관리자 페이지 회원 레포트 페이지를 5탭(개요·학습 분석·지표 분석·레벨 이력·상세 기록)으로 설계한 머지. 신규 4 API + 기존 1 API 재사용, 공통 기간 필터, 인사이트 3파트(긍정/격려/개선) 구조, 학습 진도 집계 단위를 묶음에서 콘텐츠로 바꾼 결정, 상세 기록의 드릴다운 3계층(과제→묶음→콘텐츠) 응답 표준을 정리한다. NestJS + Prisma 환경에서 명세 우선·FE Mock 선행 워크플로우로 BE 구현 전 사용자 검토를 확보한 도입 단계 마일스톤이다.

NestJSPrismaAPI 설계

🔥 시리즈별 최신

📚 블로그 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