백엔드/Prisma Prisma $extends 테넌트 격리와 $transaction 사이의 타협: 수동 orgId 주입 전략 SaaS 모드에서 Project 쿼리에 organizationId를 자동 주입하던 $extends 확장이 $transaction 콜백 안에서는 동작하지 않았다. 테넌트 격리를 포기할 수도, 트랜잭션을 포기할 수도 없어서 '수동 orgId 주입' 패턴으로 절충한 기록.
백엔드/API설계 Active, Ongoing, Completed: 주차 기반 태스크 상태 쿼리의 3가지 의미론과 그 함정 '이번 주 진행중인 태스크'를 쿼리하는 방법이 세 가지나 있었다. '주 중에 전환된', '주 동안 어느 시점이라도', '주 시작 시점에'. 말로는 비슷하지만 SQL은 전혀 다르고, 틀리면 이전 주부터 계속 진행되던 태스크가 리포트에서 사라진다.
백엔드/API설계 과거 주차 조회에서 '그 당시 최신 스프린트'는 뭐였나: weekEnd 기준 latest sprint 설계 주간 리포트 API가 '이번 주의 latest sprint' 개념으로 태스크를 골라왔는데, 과거 주차를 조회하면 '그 당시'가 아닌 '지금의' latest sprint가 튀어나왔다. carry-over 없이 버려진 태스크까지 리포트에 다시 나타나는 버그였다.
백엔드/Prisma 순차 루프를 10배 빠르게: Promise.all 병렬화 + findMany distinct 배치화로 API 응답 시간 잡기 주간 리포트 API가 과제 수에 비례하여 느려졌다. for 루프의 sprint+task 쿼리를 Promise.all로 병렬화해 10배, findFirst N회를 findMany(distinct) + createMany 2쿼리로 바꿔 50배. 두 최적화를 한 커밋에 담은 기록.
백엔드/Prisma 과거의 진실을 기록하는 법: Append-only ProjectStatusLog로 구현한 historical 주간 리포트 이번 주 주간 리포트를 보는데, 지난 달에 완료된 과제가 목록에서 사라졌다. 현재 상태(status=완료)로 필터하면 과거 주차 리포트가 오염된다 — 이 문제를 append-only 로그로 해결한 방법.
백엔드/Prisma findUnique → create의 함정: Prisma get-or-create 패턴의 P2002 레이스 컨디션과 3줄짜리 해법 '없으면 만들어'는 간단해 보이지만 동시 요청 2개가 들어오면 둘 다 'findUnique가 없다'를 거쳐 둘 다 create를 호출합니다. unique constraint에 걸려 P2002가 터지는 전형적인 get-or-create 레이스. try/catch 3줄로 우아하게 풀었습니다.
백엔드/Prisma Prisma 일괄 업데이트에서 동시성 이슈 해결하기 ($transaction 활용) 두 사용자가 동시에 일괄 상태 변경을 실행했을 때 데이터가 꼬이는 버그를 발견했습니다. Prisma $transaction으로 TOCTOU 취약점을 해결한 방법을 공유합니다.
백엔드/Prisma Prisma Extension으로 민감 데이터 암호화 자동화하기 개인정보보호법 준수를 위해 DB 민감 데이터를 암호화해야 했습니다. Prisma Extension으로 투명한 암호화를 구현하고, Blind Index로 검색 문제까지 해결한 경험을 공유합니다.
백엔드/Prisma Prisma N+1 쿼리 성능 문제 해결하기 (50% 속도 개선) API 응답이 느려서 쿼리 로그를 분석했더니 N+1 유사 패턴이 발견되었습니다. Prisma의 관계 중첩을 활용해 쿼리를 통합하고 50% 성능 개선을 달성한 방법을 소개합니다.
백엔드/Prisma Prisma Decimal to Number 변환 시 silent failure 방지하기 API에서 계산 결과가 NaN으로 표시되는 버그를 발견했습니다. Prisma Decimal 타입을 Number()로 변환하면서 발생한 silent failure를 safeNumber 패턴으로 해결한 방법을 공유합니다.