본문으로 건너뛰기

빌링 스키마

목적

Lumie에는 데이터 경계가 다른 두 가지 과금 모델이 있습니다. 플랫폼 과금은 Lumie가 학원에 SaaS 제품 비용을 청구하는 흐름을 추적합니다. 수강료 과금은 학원이 보호자 또는 학생에게 청구하는 흐름을 추적합니다. 이 ERD는 스키마 변경이 플랫폼 제어 평면 레코드와 테넌트 소유 수강료 레코드를 실수로 섞지 않도록 두 모델을 분리해 보여줍니다.

소스 경로

경로역할
lumie-backend/app/src/main/resources/db/migration/public/V28__billing_platform_tables.sql플랫폼 과금 테이블과 초기 payment_transactions 감사 테이블
lumie-backend/app/src/main/resources/db/migration/public/V29__tuition_tenant_tables.sql수강료 과금 테이블, JSON 컬럼, 테넌트 RLS
lumie-backend/app/src/main/resources/db/migration/public/V31__billing_add_missing_columns.sqlpayment_transactions.type 주석을 현재 enum 이름과 동기화
lumie-backend/app/src/main/resources/db/migration/public/V33__billing_keys_add_customer_key.sqlToss customer key 지원
lumie-backend/app/src/main/resources/db/migration/public/V34__seed_plans.sql초기 플랜 데이터
lumie-backend/app/src/main/resources/db/migration/public/V35__backfill_free_subscriptions.sql기본 subscription backfill
lumie-backend/app/src/main/resources/db/migration/public/V37__subscription_scheduled_changes.sql예약된 subscription 변경
lumie-backend/app/src/main/resources/db/migration/public/V38__create_billing_operation_locks.sqlbilling 작업 lock 테이블
lumie-backend/modules/billing/src/main/java/com/lumie/billing/domain/entity/PaymentTransaction.javaaudit 행의 현재 JPA 매핑
lumie-backend/modules/tuition/src/main/java/com/lumie/tuition/domain/entity/TuitionInvoice.javatuition invoice의 현재 JPA 매핑

플랫폼 빌링 ERD

platform billing 테이블은 cross-테넌트 Lumie 레코드입니다. tenant를 참조하지만 테넌트 RLS 테이블은 아닙니다. 접근 제어는 백엔드 권한 부여와 billing 워크플로가 담당합니다.

테넌트 수강료 ERD

tuition 테이블은 테넌트 소유 학원 레코드입니다. tenant_id, 테넌트-safe 인덱스, RLS를 유지해야 합니다. 일부 관계는 hard 결합이 모듈 소유권 경계를 넘을 때 엄격한 DB FK가 아니라 의미적 관계로 남습니다.

감사 및 멱등성

payment_transactions는 append-only audit 데이터입니다. 일반 billing 코드는 이력을 수정하는 대신 요청, 응답, webhook에 대한 audit 행을 추가해야 합니다.

검증

cd /path/to/Lumie
rg -n "total_amount|items|idempotency_key|order_id|pg_payload|billing_operation_locks" \
lumie-backend/app/src/main/resources/db/migration/public/V28__billing_platform_tables.sql \
lumie-backend/app/src/main/resources/db/migration/public/V29__tuition_tenant_tables.sql \
lumie-backend/app/src/main/resources/db/migration/public/V38__create_billing_operation_locks.sql

예상 성공 신호: tuition_invoicesitems, total_amount, status, idempotency_key가 있고, payment_transactionspg_payloadidempotency_key가 있으며, billing_operation_locks가 tenant별 lock 상태를 노출합니다.

cd /path/to/Lumie
rg -n "SUBSCRIPTION_CHARGE|SUBSCRIPTION_REFUND|ALIMTALK_RECHARGE|BILLING_KEY_ISSUE|BILLING_KEY_REVOKE" \
lumie-backend/app/src/main/resources/db/migration/public/V31__billing_add_missing_columns.sql \
lumie-backend/modules/billing/src/main/java/com/lumie/billing/domain/vo/TransactionType.java

예상 성공 신호: 검색 결과가 현재의 라이브 계약 드리프트를 명시적으로 보여줍니다. V31TAX_INVOICE_ISSUE를 언급하지만, 체크인된 Java enum에는 없습니다.

변경 체크리스트

  1. 변경이 platform billing인지 테넌트 tuition인지 결정합니다.
  2. platform subscription 테이블이 아니라 테넌트 tuition 테이블에만 RLS를 사용합니다.
  3. 외부 결제 호출의 idempotency를 유지합니다.
  4. 새로운 PG 상호작용을 도입하면 audit write를 추가하거나 갱신합니다.
  5. soft reference를 쓰더라도 테넌트 tuition 참조는 테넌트-safe하게 유지합니다.