본문으로 건너뛰기

빌링 스키마

목적

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

소스 경로

경로역할
lumie-backend/app/src/main/resources/db/migration/public/V28__billing_platform_tables.sql플랫폼 billing 테이블과 초기 payment_transactions audit 테이블
lumie-backend/app/src/main/resources/db/migration/public/V29__tuition_tenant_tables.sqltuition billing 테이블, JSON 컬럼, tenant 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-tenant Lumie 레코드입니다. tenant를 참조하지만 tenant RLS 테이블은 아닙니다. 접근 제어는 백엔드 권한 부여와 billing 워크플로가 담당합니다.

테넌트 수업료 ERD

tuition 테이블은 tenant 소유 academy 레코드입니다. tenant_id, tenant-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인지 tenant tuition인지 결정합니다.
  2. platform subscription 테이블이 아니라 tenant tuition 테이블에만 RLS를 사용합니다.
  3. 외부 결제 호출의 idempotency를 유지합니다.
  4. 새로운 PG 상호작용을 도입하면 audit write를 추가하거나 갱신합니다.
  5. soft reference를 쓰더라도 tenant tuition 참조는 tenant-safe하게 유지합니다.