"supabase db push는 이미 기록된 버전을 재적용하지 않는다"
Node별 Input/Output을 전체교체 방식으로 저장할 기능이 필요했는데, 이 작업을 시작하기 전에 먼저 이전 세션에서 진행한 작업이 실제로 커밋됐는지부터 확인해야 했습니다. 메모리와 실제 git 상태가 다를 수 있다는 걸 이미 겪어본 적이 있었기 때문입니다.
핵심 결정 포인트는 전체교체에 필요한 DELETE를 어떻게 처리할지였습니다. DELETE RLS 정책을 추가하는 방법, 전체교체 대신 다른 저장 방식을 쓰는 방법, DELETE RLS 없이 SECURITY DEFINER RPC 내부에서 처리하는 방법 세 가지 중, 프로젝트의 Hard Delete 금지 원칙을 지키면서도 기능을 구현할 수 있는 세 번째 방식을 택했습니다.
RPC를 처음 설계할 때는 3개 파라미터였는데, 다른 project의 node_id를 보내면 NOT_FOUND로 처리해야 한다는 요건을 충족하지 못한다는 걸 발견해 project_id를 추가한 4-파라미터로 재설계했습니다. 이 과정에서 이미 si-in-ai-dev에 적용된 migration이라는 걸 확인해, 기존 파일을 고치는 대신 새 버전 migration으로 처리했습니다. supabase db push가 이미 기록된 버전을 재적용하지 않는다는 사실을 이때 직접 확인했습니다.
이렇게 확립된 RPC 패턴(SECURITY DEFINER + DELETE RLS 없음 + 단일 트랜잭션 delete+insert)이 이후 여러 작업의 표준 템플릿이 됐습니다. 다만 이 시점에는 코드 레벨 검증까지만 마쳤고, 이 패턴이 하위 데이터가 있는 테이블에도 안전한지는 이후 작업에서 실제로 문제가 되어 다시 검증하게 됩니다.
프로젝트의 "Hard Delete 금지, DELETE RLS 정책 없음" 운영 원칙이 최우선이었습니다. 일반 세션이 DELETE를 실행할 수 있는 경로 자체를 열지 않으면서도 전체교체라는 기능 요구를 충족해야 했기 때문에, 이전 작업에서 이미 쓰인 SECURITY DEFINER RPC 패턴을 재사용하는 게 새로운 예외를 만드는 것보다 일관성 있는 접근이라고 판단했습니다.
관련 프로젝트
프로젝트 개요 비즈니스 프로세스 트랜스포메이션(BPR)을 지원하는 한국어 기반 웹 애플리케이션. 컨설팅 프로젝트의 AS-IS 프로세스 분석부터 TO-BE 설계, Blueprint 승인까지의 전체 워크플로우를 디지털화하는 플랫폼으로, EPIC 단위로 구조화된 백로그를 기반으로 개발 중. 역할 및 워크플로우 PM / Architect / Reviewer 역할 수행 Codex(구현 담당)에게 Task 단위 구현 프롬프트 설계 Codex 구현 결과를 git log, git grep, git status로 직접 검증 후 승인 승인 전에는 Codex가 commit하지 않는 엄격한 게이팅 프로세스 운영 한 번에 하나의 Backlog Task만 진행, Task 완료 전 다음 Task 착수 금지 기술적 의사결정 및 성과 워크스페이스/프로젝트 접근 권한을 DB 레벨(복합 FK, SECURITY DEFINER 트리거)과 애플리케이션 레벨(Server Action 권한 검증)의 이중 방어 구조로 설계 Hard Delete 미구현 원칙 하에 배열 필드 전체교체(replace)를 단일 트랜잭션 RPC로 처리하는 패턴 확립 및 재사용 AS-IS 프로세스 그래프의 순환 참조 탐지에 Tarjan SCC 알고리즘 적용, 차단 오류(Error)와 경고(Warning)를 분리한 이중 Validator 아키텍처 설계 도메인 규칙 위반을 커스텀 Postgres 에러 코드 체계(SIA0104)로 문서화하여 거버넌스 문서와 코드베이스 간 정합성 유지 AI 생성 데이터와 사람이 검증한 데이터를 구분하는 generatedbyai / verified 메타데이터 패턴을 여러 도메인 테이블에 일관되게 적용 진행 상태 ✅ EPIC-01 (인증 / 워크스페이스 / 프로젝트 접근) ✅ EPIC-02 (조직 / 산업 / 프로젝트) 🚧 EPIC-03 (AS-IS 프로세스 그래프) — 그래프 검증, Input/Output 스키마, Business Rule 스키마 구현 완료