fix: generate SaaS golden path preset - #819
Conversation
|
Warning Review limit reached
More reviews will be available in 16 minutes and 37 seconds. Learn how PR review limits work. Your organization has used up its prepaid credits, and credit purchases are no longer available. Enable the review add-on in the billing tab to keep reviews running — you're only billed for reviews past your plan's rate limits ($0.25/file). ⌛ How to resolve this issue?After more reviews become available, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans include higher PR review limits than trial, open-source, and free plans. In all cases, reviews become available again over time. During sustained high-volume PR review activity, CodeRabbit may temporarily slow when the next review becomes available. Please see our Fair Usage Limits Policy for further information. ℹ️ Review info⚙️ Run configurationConfiguration used: Organization UI Review profile: ASSERTIVE Plan: Pro Run ID: 📒 Files selected for processing (15)
📝 WalkthroughWalkthrough
ChangesSaaS Golden Path Preset
Sequence Diagram(s)sequenceDiagram
actor User
participant CLI as create-croco-app CLI
participant Options as options.ts
participant Generator as generator.ts
participant Template as saas template
User->>CLI: --preset saas 실행
CLI->>Options: validateCliOptions (assertSaasOptions)
Options-->>CLI: 비호환 플래그 있으면 에러
CLI->>Options: normalizeNonInteractiveOptions (saas 조기 반환)
CLI->>Generator: generate(targetDir, {preset: "saas"})
Generator->>Template: mergeInto("blank")
Generator->>Template: mergeInto("saas")
Generator->>Generator: installAgentRules (조건부)
Generator->>Generator: finalize()
Generator-->>User: saas 프로젝트 생성 완료
sequenceDiagram
participant DemoScript as demo:smoke
participant runSaasDemoFlow
participant InMemoryTenantStore
participant InMemoryAccessProvider
participant BillingService
participant MeteringService
participant HealthCheckService
participant assertSaasDemoSnapshot
DemoScript->>runSaasDemoFlow: 실행
runSaasDemoFlow->>InMemoryTenantStore: 테넌트 생성 및 멤버십/초대 처리
runSaasDemoFlow->>InMemoryAccessProvider: RBAC 부여 및 권한 체크
runSaasDemoFlow->>BillingService: 체크아웃 생성 및 구독 저장
runSaasDemoFlow->>MeteringService: 메터 등록 및 사용량 기록/조회
runSaasDemoFlow->>HealthCheckService: 헬스/진단 리포트 수집
runSaasDemoFlow-->>DemoScript: SaasDemoSnapshot 반환
DemoScript->>assertSaasDemoSnapshot: 스냅샷 검증
assertSaasDemoSnapshot-->>DemoScript: 통과 또는 에러
Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
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. Comment |
📊 Benchmark Results❌ Some benchmarks failed Gate failures
Updated: 2026-06-16T13:35:26.194Z · Commit: e2e3fd4 |
There was a problem hiding this comment.
Actionable comments posted: 10
🤖 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 258-273: The assertSaasOptions function is throwing generic Error
instances, which violates the RFC 7807 Problem-based error handling guideline.
Replace all throw new Error statements within the assertSaasOptions function
(checking options.api, options.apiHosting, options.backendDeploy,
options.frontendDeploy, options.webApps, and options.db) with appropriate
Problem subclass throws instead of generic Error instances to maintain
consistency with the codebase error handling contract.
In
`@packages/create-croco-app/templates/saas/apps/api-server/src/controllers/SaasController.ts`:
- Around line 6-18: The seedDemo and smokeDemo methods in the SaasController
class are exposed without any protection, allowing external callers to execute
demo flows in production. Add environment or authentication guards to both
methods to prevent execution in production environments. Either implement an
environment check that blocks execution when the app is running in production
mode, or add an authentication decorator that enforces admin-level access. Apply
the same protection to both the seedDemo and smokeDemo methods to ensure demo
endpoints cannot be triggered by unauthorized users in production.
In `@packages/create-croco-app/templates/saas/apps/api-server/src/index.ts`:
- Around line 1-10: The startup code in the main function is missing the
required global initialization of TelemetryRuntime. According to the coding
guidelines for files matching the **/apps/**/*.ts pattern, TelemetryRuntime must
be initialized at application startup at the global scope. Add an import
statement for TelemetryRuntime at the top of the file and then call
TelemetryRuntime.getInstance().init() at the module level (before the void
main() invocation) or as the first statement within the main function to ensure
it runs before any other application logic in createCrocoApp().
- Around line 4-7: The port parsing on line 4 where Number(process.env.PORT ??
3000) is assigned lacks validation, meaning invalid PORT environment variables
(e.g., PORT=abc) will result in NaN being passed directly to app.listen(port) on
line 7, causing runtime failure. Add validation after the port assignment to
check that the parsed port is a valid number (not NaN) and within the valid port
range (1-65535). If validation fails, log an explicit error message and
terminate the process using process.exit(1) before attempting to listen.
In
`@packages/create-croco-app/templates/saas/apps/api-server/src/inMemoryAdapters.ts`:
- Around line 85-105: The code is throwing generic Error instances at lines 86
(in the update method) and 104 (in the updateSettings method) when a tenant is
not found. Replace both occurrences of throw new Error(...) with an appropriate
Problem subclass that aligns with your domain's error handling contract, such as
a NotFoundProblem or equivalent Problem subclass that represents a missing
tenant scenario. This ensures consistent error handling throughout the template
and adheres to the guideline of throwing only Problem subclasses.
- Around line 68-78: The create method in the tenant adapter generates an ID
from the slug using createTenantId and directly sets it in the Map without
checking for duplicates, which silently overwrites existing tenants on ID
collision. Before calling this.tenants.set(tenant.id, tenant), add a check to
verify that tenant.id does not already exist in this.tenants, and if it does
exist, throw an appropriate error to explicitly reject the duplicate instead of
silently overwriting the existing data.
In `@packages/create-croco-app/templates/saas/apps/api-server/src/saasDemo.ts`:
- Around line 482-484: Replace the generic Error thrown when smoke validation
fails with an appropriate Problem subclass. In the condition checking if
failures.length is greater than 0, instead of throwing new Error with the "SaaS
demo smoke failed" message, instantiate and throw the relevant Problem subclass
that aligns with your codebase's error handling standards. This ensures
consistency across the template by using Problem subclasses exclusively for
error handling rather than generic Error instances.
- Around line 134-136: The publish method has two issues: First, replace any
generic Error throws (at line 483) with appropriate Problem subclass throws per
coding guidelines. Second, the singleton state cross-contamination problem
exists because the EventBusConfig singleton is retrieved dynamically in the
publish method via getEventBus(). Instead, capture the eventBus instance once
when the publisher is initialized (in the constructor or initialization code at
lines 149-153) and store it as a field on the publisher class. Then modify the
publish method to use this stored eventBus field directly, rather than
dynamically re-querying getEventBus() each time, so that each runtime instance
maintains its own isolated bus reference.
In
`@packages/create-croco-app/templates/saas/apps/api-server/src/tests/SaasDemo.spec.ts`:
- Around line 4-64: The test suite "SaaS golden path demo" is missing the
required DI Container reset for proper test isolation. Add a beforeEach hook
inside the describe block that calls Container.reset() before each test case.
This hook should be placed at the beginning of the describe block, before all
the it() test declarations, to ensure each test starts with a clean DI Container
state as per the coding guidelines.
In `@scripts/create-croco-app-generated-smoke.mts`:
- Around line 230-236: The validations array in the smoke test is missing a
check for the demo:seed script. Currently it only validates demo:smoke, which
means the demo:seed command could break without failing the validation matrix.
Add a new validation entry to the validations array with a descriptive label
(e.g., "demo seed") and the args property set to ["demo:seed"] to ensure both
seed and smoke demo commands are verified as part of the SaaS golden path smoke
test.
🪄 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
Run ID: 579bf21c-97b2-433c-810e-0500ad6ef8c7
📒 Files selected for processing (30)
.changeset/saas-golden-path.mdpackages/create-croco-app/src/cli.tspackages/create-croco-app/src/generator.tspackages/create-croco-app/src/helpers/croco-ranges.tspackages/create-croco-app/src/options.tspackages/create-croco-app/src/prompts.tspackages/create-croco-app/src/supported-options.tspackages/create-croco-app/src/tests/e2e-generation.spec.tspackages/create-croco-app/src/tests/options.spec.tspackages/create-croco-app/src/tests/templates-build.spec.tspackages/create-croco-app/src/types.tspackages/create-croco-app/templates/saas/README.md.hbspackages/create-croco-app/templates/saas/apps/api-server/package.json.hbspackages/create-croco-app/templates/saas/apps/api-server/src/app.tspackages/create-croco-app/templates/saas/apps/api-server/src/controllers/OperationsController.tspackages/create-croco-app/templates/saas/apps/api-server/src/controllers/SaasController.tspackages/create-croco-app/templates/saas/apps/api-server/src/controllers/schemas.tspackages/create-croco-app/templates/saas/apps/api-server/src/demo/seed.tspackages/create-croco-app/templates/saas/apps/api-server/src/demo/smoke.tspackages/create-croco-app/templates/saas/apps/api-server/src/inMemoryAdapters.tspackages/create-croco-app/templates/saas/apps/api-server/src/index.tspackages/create-croco-app/templates/saas/apps/api-server/src/saasDemo.tspackages/create-croco-app/templates/saas/apps/api-server/src/tests/SaasDemo.spec.tspackages/create-croco-app/templates/saas/apps/api-server/tsconfig.json.hbspackages/create-croco-app/templates/saas/libs/shared/provider-rpc/package.json.hbspackages/create-croco-app/templates/saas/libs/shared/provider-rpc/src/index.tspackages/create-croco-app/templates/saas/libs/shared/provider-rpc/tsconfig.json.hbspackages/create-croco-app/templates/saas/package.json.hbspackages/create-croco-app/templates/saas/turbo.json.hbsscripts/create-croco-app-generated-smoke.mts
Fixes #718.
Summary
create-croco-app --preset saasnow generates an installable SaaS golden path baseline that wires tenant, membership, invitation, RBAC/auth, access tuples, billing, metering, entitlements, health, and diagnostics through public Croco package APIs.The generated app includes REST controllers, contract-first RPC/OpenAPI generation commands, seed/smoke commands, in-memory providers, focused demo tests, and a README quickstart. Unsupported provider/deploy/database combinations are rejected for SaaS in both noninteractive and partial interactive CLI paths.
The generated-app smoke matrix now covers the SaaS preset with install, typecheck, build, test, OpenAPI contract generation, RPC client typecheck, and demo smoke validation.
Verification
pnpm --filter create-croco-app exec vitest run src/tests/options.spec.tspnpm --filter create-croco-app typecheckpnpm --filter create-croco-app test- 49 tests passed.pnpm --filter create-croco-app buildpnpm checkpnpm changeset-required:check -- --base origin/trunk --head HEADgit diff --checkcontract:openapismoke after install.pnpm create-croco-app:smoke- all generated app smoke cases passed, including SaaS typecheck/build/test/OpenAPI contract/demo flow.pnpm test197/197 tasks and fullpnpm typecheck196/196 tasks.Self-review gates
create-croco-app.create-croco-apppreset plumbing, the SaaS template, generator tests, and generated-app smoke coverage.Independent review
--preset saasCLI options before prompting, with regression coverage for API, web app, database, backend deploy, and frontend deploy flags.Risk
This preset intentionally uses local in-memory providers for the golden path. Production auth providers, payment providers, persistent storage, admin UI, and multi-region deployment automation remain outside this first SaaS preset slice.
Summary by CodeRabbit
Release Notes
New Features
create-croco-app --preset saas명령으로 SaaS 애플리케이션을 위한 "golden path" 기본 구성을 생성할 수 있습니다.Tests