Skip to content

feat: make generated SaaS overage delivery recoverable - #1794

Merged
kang-heewon merged 11 commits into
trunkfrom
feat/1528-metered-overage
Aug 9, 2026
Merged

feat: make generated SaaS overage delivery recoverable#1794
kang-heewon merged 11 commits into
trunkfrom
feat/1528-metered-overage

Conversation

@kang-heewon

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

Copy link
Copy Markdown
Member

Outcome

Generated SaaS applications now prove a credential-free fixed-subscription-plus-metered-overage path across local commit, provider outage, process-boundary recovery, duplicate acknowledgement, and final convergence. Stable JSON and Markdown evidence includes event IDs, delivery outcomes, backlog diagnostics, the recovery command, provider-accepted usage, and the shared team@v1 subscription and entitlement reference.

The generated usage dashboard exposes only the required billing-delivery state: local and provider usage, drift, pending count and age, retry and terminal counts, and the recovery command. Monetization contract canaries reject unbound required meters with CROCO_BILLING_METER_UNBOUND and checkout-only provider profiles with CROCO_BILLING_PROVIDER_CAPABILITY_MISSING.

Fixes #1528

Reviewer context

  • The credential-free journal and provider fixture use SQLite BEGIN IMMEDIATE transactions so committed usage survives process exit without a hand-managed stale-lock path.
  • SaaS and AI-SaaS generated roots declare Node >=22.5, the minimum release that provides node:sqlite; other presets retain the existing Node contract.
  • Recovery runs through the generated pnpm --dir apps/api-server demo:usage-recover command in a separate Node process.
  • Provider ingestion keys on stable event IDs and returns duplicate without increasing accepted usage.
  • Changesets cover the generated CLI/dashboard surface, create-croco-app preset behavior, and published recovery problem contracts.

Verification

  • Generated SaaS install/lint/typecheck/build/test/contract/DI/failure-drill/recovery/scenario smoke β€” passed
  • Exact goal-saas-api and ai-saas-golden-path generated-app paths on Node 22.23.1 β€” passed
  • @croco/cli β€” 30 files, 297 tests passed; lint, typecheck, and build passed
  • create-croco-app β€” 15 files, 144 tests passed; lint, typecheck, and build passed
  • Generated smoke script regressions β€” 41 passed
  • ContractGraph monetization regressions β€” 58 passed
  • pnpm saas-billing-golden-path:smoke β€” 10 passed after dependency-aware build
  • Pre-push workspace test β€” 236/236 tasks passed
  • Pre-push workspace typecheck β€” 235/235 tasks passed
  • git diff --check origin/trunk...HEAD β€” passed
  • CLI source E2E generated fixture typecheck β€” 8 tests passed against public package ranges
  • pnpm problem-registry:check β€” 606 codes from 606 discoveries passed

Review gates

  • Scenario correctness β€” PASS. Included and overage usage, provider outage after local commit, separate-process recovery, duplicate replay, PlanVersionRef alignment, and zero final drift/backlog are asserted in generated artifacts and tests.
  • Contract, security, and release β€” PASS. Both required negative diagnostics are exact, generated evidence excludes secrets and unstable timestamps, dependency manifests and changesets are synchronized, and default smoke remains credential-free.
  • Maintainability and minimality β€” PASS. The existing SaaS preset and generated usage dashboard are extended in place; durable fixture transitions share one transactional helper and production recovery guidance remains explicit.
  • Independent adversarial review β€” PASS after fixes. Review identified unsafe file-lock recovery races, the initial Node engine mismatch, rollback observability, and parallel fixture leakage; SQLite transitions preserve the primary diagnostic while logging rollback failures, test fixtures are process-isolated and cleaned up, and SaaS runtime metadata requires Node 22.5.

@coderabbitai

coderabbitai Bot commented Aug 9, 2026

Copy link
Copy Markdown

Review Change Stack

πŸ“ Walkthrough

Walkthrough

SaaS 생성 ν…œν”Œλ¦Ώμ΄ μ˜μ† billable usage journal, provider μž¬μ‹œλ„Β·λ³΅κ΅¬, 쀑볡 처리, plan version 증거 및 billing drift 진단을 μ§€μ›ν•©λ‹ˆλ‹€. CLI λŒ€μ‹œλ³΄λ“œμ™€ 생성 μ•± 검증도 μƒˆ μƒνƒœμ™€ contract canaryλ₯Ό κ²€μ‚¬ν•©λ‹ˆλ‹€.

Changes

SaaS metered overage

Layer / File(s) Summary
Billing contract와 persistent delivery
packages/create-croco-app/templates/saas/apps/api-server/src/controllers/monetization.ts, packages/create-croco-app/templates/saas/apps/api-server/src/demo/*, packages/create-croco-app/templates/saas/apps/api-server/src/tests/*
team@v1 monetization contract와 SQLite 기반 journalΒ·gatewayλ₯Ό μΆ”κ°€ν–ˆμŠ΅λ‹ˆλ‹€. 쀑볡 이벀트, lease, fencing token, μž¬μ‹œλ„ 및 fixture 볡ꡬλ₯Ό κ²€μ¦ν•©λ‹ˆλ‹€.
Runtime scenario와 recovery evidence
packages/create-croco-app/templates/saas/apps/api-server/src/saasDemo.ts, packages/create-croco-app/templates/saas/apps/api-server/src/demo/scenario.ts, packages/create-croco-app/templates/saas/apps/api-server/src/demo/usage-recover.ts
κ³ μ • plan version, quota 2, overage ν—ˆμš©, provider μž₯μ• , 별도 ν”„λ‘œμ„ΈμŠ€ 볡ꡬ, duplicate replay, provider 수렴 및 billing read model을 μ‹€ν–‰ν•˜κ³  λ³΄κ³ ν•©λ‹ˆλ‹€.
Dashboard billing state
packages/cli/src/commands/generateUsageDashboard.ts, packages/cli/src/tests/generateUsageDashboard.spec.ts
μ‚¬μš©λŸ‰ λŒ€μ‹œλ³΄λ“œκ°€ planVersionRef, provider μŠΉμΈλŸ‰, local usage, drift, backlog, μ‹€νŒ¨ 수 및 볡ꡬ λͺ…령을 λ°˜ν™˜ν•˜κ³  ν‘œμ‹œν•©λ‹ˆλ‹€.
Generated app contract와 validation
packages/create-croco-app/src/*, packages/create-croco-app/templates/*, scripts/create-croco-app-generated-smoke.mts, docs/*, tsconfig/contract-strict.baseline.json
SaaS 생성 앱에 Node.js >=22.5, billing μ˜μ‘΄μ„±, recovery λͺ…λ Ή 및 contract canaryλ₯Ό μ μš©ν•©λ‹ˆλ‹€. 문제 μ½”λ“œμ™€ 생성 μ•± 검증 기쀀을 κ°±μ‹ ν•©λ‹ˆλ‹€.

Estimated code review effort: 5 (Critical) | ~120 minutes

Possibly related issues

  • framework issue 1511: μ˜μ† usage billing, plan version κ³ μ •, provider 볡ꡬ 및 drift 진단 λͺ©ν‘œκ°€ 이 λ³€κ²½κ³Ό 직접 μ—°κ²°λ©λ‹ˆλ‹€.

Possibly related PRs

  • croco-dev/framework#1639: metering recovery와 idempotency λ™μž‘μ„ ν˜„μž¬ SaaS runtime에 ν†΅ν•©ν•œ λ³€κ²½κ³Ό 직접 μ—°κ²°λ©λ‹ˆλ‹€.
  • croco-dev/framework#1669: durable billable usage journal contractλ₯Ό ν˜„μž¬ templateκ³Ό recovery flowκ°€ μ‚¬μš©ν•©λ‹ˆλ‹€.
  • croco-dev/framework#1726: duplicate delivery, retry, meter state 및 provider capability 검증이 ν˜„μž¬ billing flow와 직접 μ—°κ²°λ©λ‹ˆλ‹€.
πŸš₯ Pre-merge checks | βœ… 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
βœ… Passed checks (4 passed)
Check name Status Explanation
Linked Issues check βœ… Passed 직접 μ—°κ²°λœ 이슈 #1528의 내ꡬ성, μž₯μ•  볡ꡬ, 쀑볡 λ°©μ§€, PlanVersionRef, 진단, λŒ€μ‹œλ³΄λ“œ 및 검증 μš”κ΅¬μ‚¬ν•­μ„ λ³€κ²½ 사항이 μΆ©μ‘±ν•©λ‹ˆλ‹€.
Out of Scope Changes check βœ… Passed λ³€κ²½ 사항은 SaaS 초과 μ‚¬μš©λŸ‰ 볡ꡬ, 생성 ν…œν”Œλ¦Ώ, λŒ€μ‹œλ³΄λ“œ, 계약 검증 및 κ΄€λ ¨ ν…ŒμŠ€νŠΈμ™€ λ¬Έμ„œ λ²”μœ„μ— ν¬ν•¨λ©λ‹ˆλ‹€.
Description Check βœ… Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check βœ… Passed 제λͺ©μ€ μƒμ„±λœ SaaS 초과 μ‚¬μš©λŸ‰ 전달 볡ꡬ κΈ°λŠ₯μ΄λΌλŠ” PR의 μ£Όμš” λ³€κ²½ 사항을 λͺ…ν™•ν•˜κ³  κ°„κ²°ν•˜κ²Œ μ„€λͺ…ν•©λ‹ˆλ‹€.
✨ Finishing Touches πŸ’‘ 1
πŸ“ Generate docstrings πŸ’‘
  • Create stacked PR
  • Commit on current branch
πŸ§ͺ Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/1528-metered-overage

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.

@chatgpt-codex-connector chatgpt-codex-connector 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.

πŸ’‘ Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 4699e357a2

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with πŸ‘.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@github-actions

github-actions Bot commented Aug 9, 2026

Copy link
Copy Markdown

πŸ“Š Benchmark Results

βœ… All benchmarks passed

Benchmark p75 Threshold Baseline vs Baseline Status Notes
CrocoApp constructor 44.6μs 30.0ms 8.2μs +446.0% ❌ -
CrocoApp lambdaHandler (10 controllers) 3.5ms 50.0ms 258.4μs +1250.3% ❌ -
Lambda cold-start simulation 2.6ms 80.0ms 418.1μs +521.1% ❌ -
Lambda cold-start with headers 1.6ms 80.0ms 369.7μs +339.9% ❌ -
Lambda cold-start with binary body 1.5ms 80.0ms 339.1μs +356.4% ❌ -
Lambda cold-start with query params 1.5ms 80.0ms 301.3μs +409.5% ❌ -
Lambda cold-start with authorizer context 1.5ms 80.0ms 299.8μs +405.1% ❌ -
Lambda cold-start realistic scenario 1.5ms 80.0ms 299.2μs +407.1% ❌ -
EventBusConfig.start (10 handlers) 1.7μs 10.0ms 1.4μs +20.2% ❌ -
EventPublisher.publishNow single event 1.9ΞΌs 2.0ms 1.7ΞΌs +15.4% βœ… -
DefaultHandlerResolver.resolve Γ— 10 0.1ΞΌs 5.0ms 0.1ΞΌs +0.0% βœ… -
Container.get singleton (cold) 88.0μs 5.0ms 70.3μs +25.3% ❌ -
Container.register Γ— 50 components 3.5ms 10.0ms 3.2ms +9.3% βœ… -
Container.validate (50 components) 3.9ms 20.0ms 3.4ms +16.1% βœ… -
Container.get singleton (warm) 1.7ΞΌs 500.0ΞΌs 1.6ΞΌs +3.1% βœ… -
TelemetryRuntime.init (lambda preset) 12.8ΞΌs 200.0ms 1.1ms -98.8% βœ… -
lambdaPreset config creation 1.5ΞΌs 2.0ms 1.4ΞΌs +4.3% βœ… -

Updated: 2026-08-09T18:55:48.974Z Β· Commit: 37c3a8d

@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: 13

πŸ€– 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/cli/src/commands/generateUsageDashboard.ts`:
- Around line 1126-1141: Update the Billing delivery section in
generateUsageDashboard.ts to render billingDelivery.oldestPendingAgeMs,
retryCount, and terminalFailureCount alongside the existing delivery metrics. In
packages/cli/src/tests/generateUsageDashboard.spec.ts lines 138-139, add
assertions that the generated page includes representations of all three values.

In `@packages/create-croco-app/src/node-runtime.ts`:
- Around line 19-33: SaaS Node runtime 계약이 μ—”μ§„ μ΅œμ†Œ 버전과 λ™μΌν•œ 22.5 pin을 μ‚¬μš©ν•˜λ„λ‘
λ™κΈ°ν™”ν•˜μ‹­μ‹œμ˜€. packages/create-croco-app/src/node-runtime.ts의
writeGeneratedNodeRuntimeContract()κ°€ engine range와 λ³„λ„μ˜ Node pin을 ν•¨κ»˜ λ°›μ•„ .nvmrc와
appendGeneratedNodeGuidance()에 μ „λ‹¬ν•˜λ„λ‘ λ³€κ²½ν•˜κ³ ,
packages/create-croco-app/src/generator.ts 460-465의 SaaS preset ν˜ΈμΆœμ—μ„œ 22.5λ₯Ό
μ „λ‹¬ν•˜μ‹­μ‹œμ˜€. scripts/create-croco-app-generated-smoke.mts 2456-2470의 성곡 κ²°κ³Ό
nodeRecovery 검증도 22.5 pin을 κΈ°λŒ€ν•˜λ„λ‘ κ°±μ‹ ν•˜μ‹­μ‹œμ˜€.

In
`@packages/create-croco-app/templates/saas/apps/api-server/src/demo/FileBillableUsageJournal.ts`:
- Around line 217-230: Update normalizeEvent to canonicalize the top-level
BillableUsageEvent property order before stableEvent calls JSON.stringify, while
preserving the existing dimensions sorting. Ensure semantically identical events
with different insertion orders produce the same stableEvent value and remain
idempotent.

In
`@packages/create-croco-app/templates/saas/apps/api-server/src/demo/SqliteFixtureState.ts`:
- Around line 11-52: Rename the utility module containing
readSqliteFixtureState, updateSqliteFixtureState, and resetSqliteFixtureState to
sqliteFixtureState.ts, then update the corresponding import paths in
FileBillableUsageJournal.ts and FileUsageBillingGateway.ts. Preserve all
exported functions and behavior.
- Around line 70-81: Update replaceState so invalid target or source values
throw an appropriate `@croco/problems-core` Problem subclass instead of TypeError,
using the project’s established Problem construction and diagnostic-code
conventions while preserving the existing validation behavior.

In
`@packages/create-croco-app/templates/saas/apps/api-server/src/demo/usage-recover.ts`:
- Around line 3-5: Add explicit rejection handling to the
recoverPendingBillableUsage entry point: write stable diagnostic information for
the failure to stderr and set a nonzero process exit code, while preserving the
existing stdout output for successful results.

In `@packages/create-croco-app/templates/saas/apps/api-server/src/saasDemo.ts`:
- Around line 124-128: Update BILLABLE_USAGE_STATE_DIR so billable usage SQLite
state is isolated per process, either by honoring a process-specific
CROCO_DEMO_USAGE_STATE_DIR in the test setup or by including process.pid in the
default path. Keep the journal and provider paths derived from this directory,
and preserve the inherited environment so child recovery processes reuse the
same isolated state.
- Around line 1113-1121: The generated SaaS template must throw only Problem
subclasses with stable diagnostic codes instead of generic errors. In
packages/create-croco-app/templates/saas/apps/api-server/src/saasDemo.ts#L1063,
1113-1121, 1189, 1197, and 1219, define or reuse dedicated Problem subclasses
for each failure and replace every throw new Error(...). In
packages/create-croco-app/templates/saas/apps/api-server/src/demo/SqliteFixtureState.ts#L70-L81,
update replaceState to throw a subclass from the same Problem hierarchy instead
of TypeError, preserving the existing failure conditions and messages where
applicable.
- Around line 1173-1192: Update recoverPendingBillableUsage so it does not
require OVERAGE_API_USAGE_EVENT_ID when no backlog exists. After delivery, look
up the entry optionally and validate that its state is "accepted" only when the
entry is present; preserve successful completion when the entry is absent.
- Around line 1194-1214: Update runUsageRecoveryProcess to give execFileAsync a
finite timeout, preventing the child process from hanging indefinitely. Parse
only the final non-empty stdout line, then validate the parsed object with the
existing zod dependency against the expected accepted, retryableFailed, and
terminalFailed numeric fields before returning it.

In
`@packages/create-croco-app/templates/saas/apps/api-server/src/tests/FileBillableUsageJournal.spec.ts`:
- Around line 74-91: Move the β€œpreserves concurrent provider ingestion and
duplicate acknowledgement” test out of the FileBillableUsageJournal describe
block into a new FileUsageBillingGateway.spec.ts test file, preserving its
existing assertions and setup so it follows the required class-based test naming
convention.
- Around line 16-30: Rename the test around FileBillableUsageJournal append
behavior to reflect that it only verifies sequential appends, since synchronous
DatabaseSync operations inside Promise.all cannot interleave. Apply the same
scope-accurate naming to the analogous tests near the other referenced cases,
without claiming process-level SQLite locking or true concurrency.
- Line 15: FileBillableUsageJournal ν…ŒμŠ€νŠΈμ— EVENT_CONFLICT, INVALID_LEASE,
STALE_CLAIM 각 MeteringTransitionProblem의 μ‹€νŒ¨ 경둜λ₯Ό μΆ”κ°€ν•˜μ‹­μ‹œμ˜€. 비동기 ν˜ΈμΆœμ€ rejects.toThrowλ₯Ό
μ‚¬μš©ν•΄ 였λ₯˜λ₯Ό κ²€μ¦ν•˜κ³ , κΈ°μ‘΄ 성곡 경둜 ν…ŒμŠ€νŠΈλŠ” μœ μ§€ν•˜μ‹­μ‹œμ˜€.
πŸͺ„ Autofix

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: 4d05488f-f6b8-4c79-95fd-cc2aebc043cc

πŸ“₯ Commits

Reviewing files that changed from the base of the PR and between b8fdd47 and 5078d1e.

πŸ“’ Files selected for processing (24)
  • .changeset/prove-saas-metered-overage.md
  • packages/cli/src/commands/generateUsageDashboard.ts
  • packages/cli/src/tests/generateUsageDashboard.spec.ts
  • packages/create-croco-app/src/generator.ts
  • packages/create-croco-app/src/node-runtime.ts
  • packages/create-croco-app/src/tests/e2e-generation.spec.ts
  • packages/create-croco-app/src/tests/templates-build.spec.ts
  • packages/create-croco-app/templates/ai-saas/apps/api-server/package.json.hbs
  • packages/create-croco-app/templates/saas/README.md.hbs
  • packages/create-croco-app/templates/saas/apps/api-server/package.json.hbs
  • packages/create-croco-app/templates/saas/apps/api-server/src/controllers/monetization.ts
  • packages/create-croco-app/templates/saas/apps/api-server/src/demo/FileBillableUsageJournal.ts
  • packages/create-croco-app/templates/saas/apps/api-server/src/demo/FileUsageBillingGateway.ts
  • packages/create-croco-app/templates/saas/apps/api-server/src/demo/SqliteFixtureState.ts
  • packages/create-croco-app/templates/saas/apps/api-server/src/demo/saasSmokeContract.ts
  • packages/create-croco-app/templates/saas/apps/api-server/src/demo/scenario.ts
  • packages/create-croco-app/templates/saas/apps/api-server/src/demo/usage-recover.ts
  • packages/create-croco-app/templates/saas/apps/api-server/src/saasDemo.ts
  • packages/create-croco-app/templates/saas/apps/api-server/src/tests/FileBillableUsageJournal.spec.ts
  • packages/create-croco-app/templates/saas/apps/api-server/src/tests/SaasDemo.spec.ts
  • packages/create-croco-app/templates/saas/apps/api-server/vitest.config.ts
  • packages/create-croco-app/templates/saas/package.json.hbs
  • scripts/create-croco-app-generated-smoke.mts
  • scripts/tests/create-croco-app-generated-smoke.spec.ts

Comment thread packages/cli/src/commands/generateUsageDashboard.ts
Comment thread packages/create-croco-app/src/node-runtime.ts Outdated
Comment thread packages/create-croco-app/templates/saas/apps/api-server/src/saasDemo.ts Outdated
@kang-heewon
kang-heewon force-pushed the feat/1528-metered-overage branch 3 times, most recently from 8cbc97c to fb4c475 Compare August 9, 2026 12:29

@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: 6

πŸ€– 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/cli/src/tests/generateUsageDashboard.spec.ts`:
- Around line 517-521: Update the generateUsageDashboard test fixture around
usageBillingReadModel.getSnapshot to accept and record the meterIds argument,
then assert that only required billing meters are passed. Add a meter without
billing classification to the meterRegistry fixture and verify it is excluded,
replacing the current string-based filter(isRequiredBillingMeter) check with an
assertion on the captured arguments.

In `@packages/create-croco-app/src/generator.ts`:
- Around line 461-469: Use the shared isSaasPreset type guard from options.ts
instead of duplicating the SaaS preset condition. In
packages/create-croco-app/src/generator.ts lines 461-469, evaluate isSaasPreset
once in finalize and reuse the result for both arguments to
writeGeneratedNodeRuntimeContract; in
packages/create-croco-app/src/cli-result.ts lines 53-61, import and use
isSaasPreset instead of computing a local condition in createSuccessResult.

In
`@packages/create-croco-app/templates/saas/apps/api-server/src/demo/sqliteFixtureState.ts`:
- Around line 41-46: Update the catch block in the transaction flow around
transactionStarted so a failed database.exec("ROLLBACK") is caught and
suppressed, then always rethrow the original caught error. Keep the existing
conditional rollback behavior and database.close() cleanup unchanged.

In `@packages/create-croco-app/templates/saas/apps/api-server/src/saasDemo.ts`:
- Around line 132-141: Derive RecoveryDeliveryResult from recoveryDeliverySchema
with z.infer instead of maintaining a duplicate object type, and update the
delivery result handling around the existing β€œas RecoveryDeliveryResult” cast to
rely on the inferred type without casting.
- Around line 285-297: Change getCurrentPlanVersion from an instance arrow
property to a prototype class method, matching the declaration style of
getCurrentPlanId while preserving its existing async logic and return behavior.

In
`@packages/create-croco-app/templates/saas/apps/api-server/src/tests/FileUsageBillingGateway.spec.ts`:
- Around line 13-32: 파일 μ‚¬μš©λŸ‰ κ²Œμ΄νŠΈμ›¨μ΄ ν…ŒμŠ€νŠΈμ— provider μž₯μ•  경둜λ₯Ό μΆ”κ°€ν•˜μ‹­μ‹œμ˜€.
`FileUsageBillingGateway` μΈμŠ€ν„΄μŠ€μ—μ„œ `setAvailable(false)`λ₯Ό ν˜ΈμΆœν•œ λ’€ `ingest`κ°€
`PolarRetryableUpstreamProblem`을 throwν•˜λŠ”μ§€ `rejects.toThrow`둜 κ²€μ¦ν•˜κ³ , κΈ°μ‘΄ 정상 처리 ν…ŒμŠ€νŠΈλŠ”
μœ μ§€ν•˜μ‹­μ‹œμ˜€.
πŸͺ„ Autofix

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: c2281570-ded6-4497-a5c0-7f9b0bf42f8b

πŸ“₯ Commits

Reviewing files that changed from the base of the PR and between 5078d1e and aadf667.

β›” Files ignored due to path filters (1)
  • packages/problems-core/src/generated/problem-code-registry.ts is excluded by !**/generated/**
πŸ“’ Files selected for processing (23)
  • .changeset/prove-saas-metered-overage.md
  • docs/problem-code-registry.json
  • packages/cli/src/commands/generateUsageDashboard.ts
  • packages/cli/src/tests/generateUsageDashboard.spec.ts
  • packages/create-croco-app/src/cli-result.ts
  • packages/create-croco-app/src/generator.ts
  • packages/create-croco-app/src/node-runtime.ts
  • packages/create-croco-app/src/tests/cli-result.spec.ts
  • packages/create-croco-app/src/tests/e2e-generation.spec.ts
  • packages/create-croco-app/src/tests/templates-build.spec.ts
  • packages/create-croco-app/templates/ai-saas/apps/api-server/package.json.hbs
  • packages/create-croco-app/templates/ai-saas/package.json.hbs
  • packages/create-croco-app/templates/saas/apps/api-server/src/demo/FileBillableUsageJournal.ts
  • packages/create-croco-app/templates/saas/apps/api-server/src/demo/FileUsageBillingGateway.ts
  • packages/create-croco-app/templates/saas/apps/api-server/src/demo/sqliteFixtureState.ts
  • packages/create-croco-app/templates/saas/apps/api-server/src/demo/usage-recover.ts
  • packages/create-croco-app/templates/saas/apps/api-server/src/problems.ts
  • packages/create-croco-app/templates/saas/apps/api-server/src/saasDemo.ts
  • packages/create-croco-app/templates/saas/apps/api-server/src/tests/FileBillableUsageJournal.spec.ts
  • packages/create-croco-app/templates/saas/apps/api-server/src/tests/FileUsageBillingGateway.spec.ts
  • packages/docs/src/content/docs/en/reference/problem-recovery-cookbook.md
  • scripts/create-croco-app-generated-smoke.mts
  • tsconfig/contract-strict.baseline.json
πŸ’€ Files with no reviewable changes (1)
  • packages/docs/src/content/docs/en/reference/problem-recovery-cookbook.md

Comment thread packages/cli/src/tests/generateUsageDashboard.spec.ts
Comment thread packages/create-croco-app/src/generator.ts
Comment thread packages/create-croco-app/templates/saas/apps/api-server/src/saasDemo.ts Outdated
@kang-heewon
kang-heewon force-pushed the feat/1528-metered-overage branch from aadf667 to 20c3f5a Compare August 9, 2026 14:13

@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: 3

πŸ€– 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/create-croco-app/src/options.ts`:
- Around line 425-427: Update the public type predicate isSaasPreset so its
SaasPreset return type is externally resolvable: either export SaasPreset or
stop referencing it in the exported predicate signature by defining the
equivalent predicate type inline. Preserve the existing "saas" and "ai-saas"
narrowing behavior.

In `@packages/create-croco-app/templates/saas/apps/api-server/src/saasDemo.ts`:
- Around line 988-994: Update the metering object in the saasDemo flow so
metering.recordedValue stores the local recorded usage total rather than
billableUsage.providerAcceptedUsage; reuse the existing currentUsage value if it
is that local aggregate, while leaving
usageBillingReadModel.providerAcceptedUsage as the provider-accepted evidence.

In
`@packages/create-croco-app/templates/saas/apps/api-server/src/tests/ExecutableAssurance.spec.ts`:
- Around line 20-23: Update the temporary directory construction in
ExecutableAssurance.spec.ts to use node:os tmpdir() instead of
process.env.TMPDIR with a /tmp fallback, matching the approach used by
FileUsageBillingGateway.spec.ts and preserving the existing
croco-executable-assurance path suffix.
πŸͺ„ Autofix

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: e4c6d770-d2e9-455c-b7a6-042458c7f732

πŸ“₯ Commits

Reviewing files that changed from the base of the PR and between aadf667 and 20c3f5a.

β›” Files ignored due to path filters (1)
  • packages/problems-core/src/generated/problem-code-registry.ts is excluded by !**/generated/**
πŸ“’ Files selected for processing (12)
  • docs/problem-code-registry.json
  • packages/cli/src/tests/generateUsageDashboard.spec.ts
  • packages/create-croco-app/src/cli-result.ts
  • packages/create-croco-app/src/generator.ts
  • packages/create-croco-app/src/options.ts
  • packages/create-croco-app/templates/saas/apps/api-server/src/demo/sqliteFixtureState.ts
  • packages/create-croco-app/templates/saas/apps/api-server/src/saasDemo.ts
  • packages/create-croco-app/templates/saas/apps/api-server/src/tests/ExecutableAssurance.spec.ts
  • packages/create-croco-app/templates/saas/apps/api-server/src/tests/FileUsageBillingGateway.spec.ts
  • packages/docs/src/content/docs/en/reference/problem-recovery-cookbook.md
  • scripts/create-croco-app-generated-smoke.mts
  • tsconfig/contract-strict.baseline.json

Comment thread packages/create-croco-app/src/options.ts Outdated
@kang-heewon
kang-heewon force-pushed the feat/1528-metered-overage branch from 20c3f5a to 522b154 Compare August 9, 2026 18:07
@kang-heewon
kang-heewon force-pushed the feat/1528-metered-overage branch from 522b154 to 279d1a6 Compare August 9, 2026 18:50
@kang-heewon
kang-heewon merged commit a458c5c into trunk Aug 9, 2026
10 of 11 checks passed
@kang-heewon
kang-heewon deleted the feat/1528-metered-overage branch August 9, 2026 19:49
@reviewlift

reviewlift Bot commented Aug 10, 2026

Copy link
Copy Markdown

PR 이해

ν™•μΈλœ λ²”μœ„ λ‚΄μ—μ„œ PR의 ꡬ체적인 λ³€κ²½ μ˜λ„λ₯Ό μš”μ•½ν•  수 μ—†μŠ΅λ‹ˆλ‹€.

μ‹œμŠ€ν…œ 영ν–₯

ν™•μΈλœ λ²”μœ„ λ‚΄μ—μ„œ 영ν–₯ λ°›λŠ” μ‹œμŠ€ν…œ μ˜μ—­μ„ νŒŒμ•…ν•  수 μ—†μŠ΅λ‹ˆλ‹€.

Merge νŒλ‹¨

βœ… λ¨Έμ§€ κ°€λŠ₯ β€” λ¨Έμ§€λ₯Ό 막을 리슀크 μ—†μŒ

  • Blocker: 0건
  • Critical: 0건
  • Recommendation: 0건

Must-fix

  • μ—†μŒ

Recommended

  • μ—†μŒ

핡심 리슀크

ν™•μΈλœ λ²”μœ„ λ‚΄μ—μ„œ λ¨Έμ§€λ₯Ό λ§‰κ±°λ‚˜ μš°μ„  μ‘°μΉ˜κ°€ ν•„μš”ν•œ 핡심 λ¦¬μŠ€ν¬λŠ” λ°œκ²¬λ˜μ§€ μ•Šμ•˜μŠ΅λ‹ˆλ‹€.

ν•œ 단계 κ°•ν™” μ œμ•ˆ

ν™•μΈλœ λ²”μœ„ λ‚΄μ—μ„œ μš°μ„  μ œμ•ˆν•  ν•œ 단계 κ°•ν™” λ°©ν–₯이 μ—†μŠ΅λ‹ˆλ‹€.

λ‹€μŒ μŠ€ν… λ©”λͺ¨

ν™•μΈλœ λ²”μœ„ λ‚΄μ—μ„œ λ‹€μŒ μŠ€ν…μ„ ꡬ체적으둜 정리할 수 μ—†μŠ΅λ‹ˆλ‹€.

전체 리뷰: ReviewLift λŒ€μ‹œλ³΄λ“œμ˜ 리뷰 μƒμ„Έμ—μ„œ ν™•μΈν•˜μ„Έμš”.


Review powered by ReviewLift

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.

[create-croco-app] Prove metered overage in the SaaS golden path

1 participant