새 대상의 기본 차단에는 새 대상을 구분할 방법이 필요하다

라이선스에 역할·신분그룹을 지정하는 것과 학교 운영자가 사용을 허용하는 것은 다른 정책이다. AI Commons에서는 새로 편입한 역할·그룹의 접근을 false로 시작하게 했다. 운영자가 명시적으로 허용한 뒤 사용할 수 있게 한 것이다.

그런데 기존 수정 API는 대상 항목을 전부 삭제하고 다시 만들었다. 생성되는 모든 행에 false를 넣으면 같은 대상 목록을 재저장하는 것만으로 기존 대상도 차단된다. 새 기본값을 넣기 전에 유지 대상의 정체성부터 보존해야 했다.

유지 대상은 ID와 접근 배분을 함께 남긴다

트랜잭션 안에서 기존 비USER 항목을 조회하고 (targetType, value)를 키로 새 목록과 대조한다. 제거 대상은 정확한 행 ID로 삭제하고 추가 대상만 생성한다. 같은 역할이나 그룹이 유지되면 행 ID도 유지한다.

역할 A·B에서 A·C로 바꾸는 예시
대상분류대상 행접근 배분
A유지기존 ID 보존기존 설정 또는 상속 유지
B삭제해당 ID 삭제정리
C추가새 행 생성false로 시작

개별 사용자 USER 명단은 이 diff와 false 기본값 적용에서 제외한다. 학교 운영자가 직접 추가하는 명단은 추가 자체가 허용이라는 기존 의미가 있기 때문이다. 역할·그룹의 편입 정책을 개인 사용자에게 그대로 적용하지 않는다.

새 목록 전체가 아니라 유지 대상의 배분만 보존한다

배분 청소의 기준은 유지 집합이다. 제거 대상과 대상 없는 고아 배분뿐 아니라, 새로 추가할 대상에 우연히 남아 있는 과거 배분도 삭제한다. 새 false 배분이 기존 유일 키와 충돌하는 것을 막고, 재편입 대상을 기존 허용값으로 시작시키지 않기 위해서다.

대상을 제거한 뒤 다시 추가하면 유지 대상이 아니라 새 대상이 된다. 새 접근 배분에는 사용량 값을 넣지 않는다. 사용량 상속 계약에 따라 사용량 컬럼 null은 전역 기본값을 따르므로 접근 행을 만드는 것만으로 개인 한도가 고정되지 않는다.

테스트는 유지 역할·그룹의 무삭제, 신규만 생성, 제거 ID 지정, USER 제외, 새 역할·그룹에만 false 배분 생성을 확인한다. mock Prisma 트랜잭션 검사이므로 실제 병렬 편집이나 격리 수준의 검증은 아니다. 전량 교체보다 조회와 집합 연산, 잔여 배분 정리가 늘어나지만 새 기본값을 기존 대상에 적용하지 않는 쓰기 계약을 표현할 수 있다.