Skip to content

feat: verify usage billing provider conformance - #1726

Merged
kang-heewon merged 4 commits into
trunkfrom
issue-1527-usage-billing-conformance
Aug 1, 2026
Merged

feat: verify usage billing provider conformance#1726
kang-heewon merged 4 commits into
trunkfrom
issue-1527-usage-billing-conformance

Conversation

@kang-heewon

@kang-heewon kang-heewon commented Aug 1, 2026

Copy link
Copy Markdown
Member

Outcome

@croco/testing now provides a versioned, machine-readable usage-billing conformance contract. Usage-capable providers must prove one-to-one bounded batch receipts, duplicate replay without a second meter increment, explicit empty and populated meter states, 429/5xx/timeout retry classification, invalid meter/schema terminal classification, stable public Problems, raw-response redaction, and credential-gated real-provider smoke coverage.

Polar runs the same suite to certify that its unsupported usage capability fails through the public capability Problem, and provider certification metadata records that evidence.

Fixes #1527

Verification

  • pnpm --filter @croco/testing typecheck
  • pnpm --filter @croco/testing test — 126 tests passed.
  • pnpm --filter @croco/billing-polar test — 87 tests passed; 2 credential-gated live-smoke tests skipped.
  • Package lint checks and pnpm public-api:check passed.
  • Pre-push workspace test and typecheck gates passed.

Review gates

  • Correctness and regression — PASS. Stateful fake-adapter coverage proves replay meter-state invariance, bounded mixed receipts, explicit meter states, and all required failure fixtures.
  • API, security, compatibility, and release — PASS. New testing exports have a versioned manifest and public API snapshot; the changeset covers @croco/testing; raw response samples are required redaction checks.
  • Maintainability and minimality — PASS. The existing billing conformance helper is extended in place, with Polar limited to its explicit unavailable-capability evidence.
  • Independent adversarial review — CLEAN. Fixture execution correlation, retry classification, redaction, and type safety were independently reviewed.

Residual risk

The real-provider profile remains deliberately opt-in and credential-gated; ordinary CI uses the deterministic reference adapter.

Summary by CodeRabbit

  • 새로운 기능

    • 사용량 기반 과금 제공자의 적합성 검증을 지원합니다.
    • 중복 이벤트, 부분 배치, 미터 상태, 재시도 가능·최종 실패 시나리오를 검증합니다.
    • 지원 및 미지원 기능에 대한 적합성 증거와 공개 오류 동작을 확인합니다.
    • 실제 결제 제공자를 대상으로 선택적 스모크 테스트를 실행할 수 있습니다.
    • Polar의 사용량 기반 과금 미지원 제한사항을 문서에 반영했습니다.
  • 문서

    • 사용량 청구 적합성 검증 범위와 제공자별 지원 현황을 추가했습니다.

@coderabbitai

coderabbitai Bot commented Aug 1, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@kang-heewon, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 56 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 5afbbfa5-91f5-4a28-b132-7f8257ebd257

📥 Commits

Reviewing files that changed from the base of the PR and between bde2bc0 and 85eb1d7.

📒 Files selected for processing (4)
  • docs/package-docs-report.md
  • packages/testing/src/libs/billing-provider-conformance.ts
  • packages/testing/src/tests/ConformanceContract.spec.ts
  • packages/testing/src/tests/testing.spec.ts
📝 Walkthrough

Walkthrough

사용량 청구 conformance 범위를 추가합니다. 중복 replay, 부분 배치, 미터 상태, retryable·terminal 오류, 미지원 capability를 검증합니다. Capability manifest와 공개 타입을 제공하고, Polar에 미지원 usage 시나리오를 연결합니다.

Changes

사용량 청구 적합성 검증

Layer / File(s) Summary
Conformance 계약과 공개 타입
packages/testing/src/libs/billing-provider-conformance.ts, packages/testing/src/index.ts, public-api-surface.snapshot.json, .changeset/usage-billing-conformance.md
사용량 fixture, 실패 시나리오, gateway 옵션, live smoke gate, capability evidence 및 manifest 타입을 추가합니다. 관련 타입을 공개 export와 API snapshot에 반영합니다.
사용량 검증 실행과 manifest 생성
packages/testing/src/libs/billing-provider-conformance.ts, packages/testing/src/tests/ConformanceContract.spec.ts
이벤트 삽입, 중복 replay, 부분 배치, 빈 상태·채워진 미터 상태를 검증합니다. HTTP 429·5xx와 timeout을 retryable로 분류하고, 잘못된 미터·스키마를 terminal로 분류합니다. Capability evidence와 동결된 manifest를 생성합니다.
테스트 gateway와 계약 테스트
packages/testing/src/tests/testing.spec.ts, packages/testing/src/tests/ConformanceContract.spec.ts
인메모리 gateway가 중복 이벤트를 제거하고 미터 사용량을 누적합니다. 실패 gateway가 공개 Problem과 업스트림 분류 정보를 생성합니다. 계약 테스트가 사용량 case와 manifest를 검증합니다.
Polar 미지원 capability와 문서 증거
packages/billing-polar/src/tests/PolarBillingGateway.spec.ts, docs/package-catalog.json
Polar에 checkout만 제공하는 미지원 usage 시나리오를 추가합니다. package catalog에 usage-billing 미지원 및 conformance 범위를 기록합니다.

Estimated code review effort: 4 (Complex) | ~45 minutes

Sequence Diagram(s)

sequenceDiagram
  participant ConformanceContract
  participant BillingProviderConformanceSuite
  participant UsageBillingGateway
  participant ProviderManifest
  ConformanceContract->>BillingProviderConformanceSuite: 사용량 fixture와 실패 시나리오 제공
  BillingProviderConformanceSuite->>UsageBillingGateway: 이벤트 삽입, replay, 미터 조회
  UsageBillingGateway-->>BillingProviderConformanceSuite: 영수증, 상태, 공개 Problem
  BillingProviderConformanceSuite->>ProviderManifest: capability evidence와 case 목록 기록
Loading

Possibly related issues

Possibly related PRs

  • croco-dev/framework#1637 — 동일한 billing provider conformance framework에 licensed-quantity와 usage-billing 시나리오를 확장하는 관계입니다.
  • croco-dev/framework#1669 — 이 PR의 사용량 conformance가 검증하는 journal 및 delivery lifecycle 구현과 직접 연결됩니다.
  • croco-dev/framework#1630 — 사용량 값과 미터링 검증의 정수 계약이 이 PR의 conformance 시나리오와 연결됩니다.
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed 제목이 사용량 청구 제공자 적합성 검증이라는 주요 변경 사항을 간결하고 명확하게 설명합니다.
Linked Issues check ✅ Passed 구현은 중복 재생, 부분 배치, 실패 분류, 미지원 기능, 미터 상태, 공개 Problem 보호, Polar 실행 및 인증 증거 요구사항을 충족합니다.
Out of Scope Changes check ✅ Passed 변경 사항은 사용량 청구 적합성 계약, 공개 타입, 테스트, Polar 증거 및 릴리스 메타데이터 범위에 포함됩니다.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch issue-1527-usage-billing-conformance

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 8

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@packages/testing/src/libs/billing-provider-conformance.ts`:
- Around line 543-552: Update UsageBillingConformanceFixtures.customerMeterState
to use Omit<CustomerMeterState, "updatedAt"> and add an optional hook for
validating updatedAt. In
packages/testing/src/libs/billing-provider-conformance.ts lines 543-552 and
597-601, compare only billingAccountId, meterId, and value for
beforeReplay/afterReplay; delegate updatedAt checks to the hook or verify only
that replay does not move it backward. Leave the empty-state assertion around
line 590 unchanged.
- Around line 271-275: Update the capability property in
BillingProviderConformanceCapabilityEvidence to use the existing
BillingProviderCapability type instead of the "usage" literal, reusing the
import already present for BillingProviderCapabilityConformanceOptions.required.
- Around line 1004-1016: Consolidate assertThrowsProblem into
assertRejectsWithProblem so one helper handles both synchronous throws and
rejected promises. Invoke the supplied callback through the async path, await
its result, and validate any caught value is a Problem before returning it.
Update callers to use assertRejectsWithProblem and remove the redundant
assertThrowsProblem helper.
- Around line 1018-1021:
packages/testing/src/libs/billing-provider-conformance.ts의
usage.partialBatch.expectedReceipts와 assertUsageReceipts를 업데이트해 receipt 구조와 상태
유니온을 재선언하지 말고 packages/billing-core/src/index.ts의 UsageBillingBatchReceipt 및
UsageBillingEventReceipt에서 타입을 파생시키십시오. 해당 upstream 타입을 기준으로 receipts와 expected의
값 타입이 연결되도록 수정하고, 두 위치(166-175, 1018-1021)의 중복 선언을 모두 제거하십시오.
- Around line 705-714: Update the default enablement check in the gate handling
around AuthProviderLiveSmokeGate so required environment variables enable live
usage billing conformance only when their values are non-empty, matching the
existing AuthProviderLiveSmokeGate rule; preserve custom gate.isEnabled behavior
unchanged.

In `@packages/testing/src/tests/ConformanceContract.spec.ts`:
- Around line 609-611: Extend the manifest immutability assertions in the
conformance suite test to verify every capability evidence object in
suite.manifest.capabilityEvidence and each nested caseNames array is frozen,
while retaining the existing top-level checks.

In `@packages/testing/src/tests/testing.spec.ts`:
- Around line 1846-1879: Update the shared failure-scenario run callbacks for
http429, http5xx, and timeout to pass the fixture’s events collection to
gateway.ingest instead of an empty array. Preserve the existing gateway
construction and failure assertions so these scenarios exercise real provider
adapters with an actual event batch.
- Around line 243-275: Update FailingUsageBillingGateway to implement
UsageBillingGateway directly instead of extending InMemoryUsageBillingGateway,
preserving its existing ingest and getCustomerMeterState failure behavior.
Narrow fixture.kind to the existing conformance contract union if available, and
replace string comparisons in createProblem with a Set-based retryable-kind
check so invalid scenario names fail type checking and retry classification
remains exhaustive.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: df26e98a-6efb-47b0-83d9-e45679a02f58

📥 Commits

Reviewing files that changed from the base of the PR and between 743a99d and bde2bc0.

📒 Files selected for processing (8)
  • .changeset/usage-billing-conformance.md
  • docs/package-catalog.json
  • packages/billing-polar/src/tests/PolarBillingGateway.spec.ts
  • packages/testing/src/index.ts
  • packages/testing/src/libs/billing-provider-conformance.ts
  • packages/testing/src/tests/ConformanceContract.spec.ts
  • packages/testing/src/tests/testing.spec.ts
  • public-api-surface.snapshot.json

Comment thread packages/testing/src/libs/billing-provider-conformance.ts
Comment thread packages/testing/src/libs/billing-provider-conformance.ts Outdated
Comment thread packages/testing/src/libs/billing-provider-conformance.ts
Comment thread packages/testing/src/libs/billing-provider-conformance.ts Outdated
Comment thread packages/testing/src/libs/billing-provider-conformance.ts Outdated
Comment thread packages/testing/src/tests/ConformanceContract.spec.ts
Comment thread packages/testing/src/tests/testing.spec.ts Outdated
Comment thread packages/testing/src/tests/testing.spec.ts
@github-actions

github-actions Bot commented Aug 1, 2026

Copy link
Copy Markdown

📊 Benchmark Results

✅ All benchmarks passed

Benchmark p75 Threshold Baseline vs Baseline Status Notes
CrocoApp constructor 38.0μs 30.0ms 8.2μs +364.6% -
CrocoApp lambdaHandler (10 controllers) 2.3ms 50.0ms 258.4μs +806.4% -
Lambda cold-start simulation 1.8ms 80.0ms 418.1μs +334.9% -
Lambda cold-start with headers 1.6ms 80.0ms 369.7μs +337.8% -
Lambda cold-start with binary body 1.7ms 80.0ms 339.1μs +407.1% -
Lambda cold-start with query params 1.6ms 80.0ms 301.3μs +435.7% -
Lambda cold-start with authorizer context 1.6ms 80.0ms 299.8μs +432.4% -
Lambda cold-start realistic scenario 1.6ms 80.0ms 299.2μs +427.1% -
EventBusConfig.start (10 handlers) 2.0μs 10.0ms 1.4μs +38.7% -
EventPublisher.publishNow single event 2.1μs 2.0ms 1.7μs +24.6% -
DefaultHandlerResolver.resolve × 10 0.1μs 5.0ms 0.1μs -13.8% -
Container.get singleton (cold) 80.6μs 5.0ms 70.3μs +14.7% -
Container.register × 50 components 3.5ms 10.0ms 3.2ms +9.4% -
Container.validate (50 components) 3.9ms 20.0ms 3.4ms +15.4% -
Container.get singleton (warm) 2.0μs 500.0μs 1.6μs +19.7% -
TelemetryRuntime.init (lambda preset) 2.3μs 200.0ms 1.1ms -99.8% -
lambdaPreset config creation 1.5μs 2.0ms 1.4μs +8.0% -

Updated: 2026-08-01T20:34:18.990Z · Commit: b280fcf

@kang-heewon
kang-heewon merged commit cadc8b7 into trunk Aug 1, 2026
12 checks passed
@kang-heewon
kang-heewon deleted the issue-1527-usage-billing-conformance branch August 1, 2026 21:05
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[testing] Add usage-billing provider conformance coverage

1 participant