Skip to content

fix: enforce strict generated contract graphs - #1217

Merged
kang-heewon merged 1 commit into
trunkfrom
fix/1184-strict-contract-graph
Jul 5, 2026
Merged

fix: enforce strict generated contract graphs#1217
kang-heewon merged 1 commit into
trunkfrom
fix/1184-strict-contract-graph

Conversation

@kang-heewon

@kang-heewon kang-heewon commented Jul 4, 2026

Copy link
Copy Markdown
Member

Fixes #1184.

Summary

  • Makes OpenAPI and RPC codegen build strict ContractGraph schema and Problem metadata by default, with legacy compatibility available only through explicit --compatibility-* opt-outs.
  • Adds --fail-on-diagnostics and wires generated app contract scripts to fail on strict warnings/errors before OpenAPI or RPC artifacts are written.
  • Updates generated 1.0 app templates and the usage dashboard generator to declare route contracts, response/body/query/param schemas, and generated client Problem unions.
  • Records explicit empty Problem surfaces for routes that intentionally expose never failure unions, and keeps extra Problem metadata outside the route contract as a ContractGraph error.
  • Documents strict vs compatibility mode and includes patch changesets for the affected publishable packages.

Verification

  • COREPACK_ENABLE_DOWNLOAD_PROMPT=0 corepack pnpm --filter @croco/openapi-spec exec vitest run src/tests/Cli.spec.ts --reporter=verbose - passed.
  • COREPACK_ENABLE_DOWNLOAD_PROMPT=0 corepack pnpm --filter @croco/rpc-codegen exec vitest run src/tests/Cli.spec.ts src/tests/ContractCheckCli.spec.ts src/tests/codegen.spec.ts --reporter=verbose - passed.
  • COREPACK_ENABLE_DOWNLOAD_PROMPT=0 corepack pnpm --filter @croco/cli exec vitest run src/tests/generateUsageDashboard.spec.ts --reporter=verbose - passed.
  • COREPACK_ENABLE_DOWNLOAD_PROMPT=0 corepack pnpm --filter @croco/cli test:e2e -- --runInBand - passed, 9 integration tests.
  • COREPACK_ENABLE_DOWNLOAD_PROMPT=0 corepack pnpm --filter @croco/protocols-core exec vitest run src/tests/extractRouteIR.spec.ts src/tests/ContractGraph.spec.ts --reporter=verbose - passed, 66 tests.
  • COREPACK_ENABLE_DOWNLOAD_PROMPT=0 corepack pnpm exec vitest run scripts/tests/create-croco-app-generated-smoke.spec.ts --config vitest.config.ts --reporter=verbose - passed.
  • COREPACK_ENABLE_DOWNLOAD_PROMPT=0 corepack pnpm exec vitest run scripts/tests/problem-registry.spec.ts --config vitest.config.ts --reporter=verbose - passed, 15 tests.
  • COREPACK_ENABLE_DOWNLOAD_PROMPT=0 corepack pnpm --filter create-croco-app exec vitest run src/tests/templates-build.spec.ts --reporter=verbose - passed, 11 tests.
  • COREPACK_ENABLE_DOWNLOAD_PROMPT=0 corepack pnpm --filter create-croco-app test - passed, 93 tests.
  • COREPACK_ENABLE_DOWNLOAD_PROMPT=0 corepack pnpm static-misuse:check - passed.
  • COREPACK_ENABLE_DOWNLOAD_PROMPT=0 corepack pnpm problem-registry:write - passed, 412 codes from 412 discoveries.
  • COREPACK_ENABLE_DOWNLOAD_PROMPT=0 CROCO_GENERATED_SMOKE_CASES=goal-saas-api,admin-console-starter,saas-golden-path,saas-cloudflare-profile,saas-lambda-profile,ai-saas-golden-path corepack pnpm create-croco-app:smoke - passed.
  • COREPACK_ENABLE_DOWNLOAD_PROMPT=0 corepack pnpm create-croco-app:smoke - passed, all generated app smoke cases.
  • COREPACK_ENABLE_DOWNLOAD_PROMPT=0 corepack pnpm check - passed.
  • COREPACK_ENABLE_DOWNLOAD_PROMPT=0 corepack pnpm release-docs:check - passed.
  • COREPACK_ENABLE_DOWNLOAD_PROMPT=0 corepack pnpm changeset-required:check -- --base origin/trunk --head HEAD - passed.
  • git diff --check HEAD^ HEAD - passed.
  • Pre-push hook auto-changeset, test, and typecheck passed on the pushed branch after the final amend; cached rerun reported 225/225 test tasks and 224/224 typecheck tasks.

Self-review gates

  • Correctness/regression: PASS. Generated app scripts now fail on strict ContractGraph diagnostics, route contracts carry schema and Problem evidence, and smoke canaries prove missing strict Problem/schema metadata blocks generated artifacts.
  • API/release compatibility: PASS. Strict behavior is now the default for codegen paths, compatibility remains explicit through documented opt-out flags, and patch changesets cover the affected packages.
  • Maintainability/minimality: PASS. The change stays within existing ContractGraph, codegen CLI, template, smoke, and registry surfaces without adding dependencies.

Notes

  • Full generated app smoke emitted non-blocking toolchain warnings from existing dependencies, but all smoke cases passed.
  • Typecheck generated local API-doc output during verification and pre-push; that generated output was cleaned before PR creation/update.

Summary by CodeRabbit

  • New Features
    • 생성 앱/템플릿에서 strict ContractGraph 검증이 기본으로 적용되고, 진단이 있을 때 OpenAPI/RPC 산출물이 차단되도록 안내 및 설정이 강화되었습니다.
    • 계약 기반(라우트 상수/계약 문제 응답) 라우팅이 템플릿 전반으로 확장되었습니다.
  • Bug Fixes
    • 문제 응답(Problem) 선언/응답 메타데이터 처리의 엄격한 판정 로직이 개선되었습니다.
  • Documentation
    • strict/compatibility 옵션과 생성 실패 조건(차단 기준) 문서가 업데이트되었습니다.
  • Tests
    • CLI 및 스키마/진단 관련 시나리오 검증 테스트가 보강되었습니다.

@coderabbitai

coderabbitai Bot commented Jul 4, 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: 53 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

Run ID: edb9899e-c78a-4e34-9264-de9dd05fcd66

📥 Commits

Reviewing files that changed from the base of the PR and between 4a51127 and ea214a0.

⛔ Files ignored due to path filters (1)
  • packages/problems-core/src/generated/problem-code-registry.ts is excluded by !**/generated/**
📒 Files selected for processing (64)
  • .changeset/strict-generated-contract-graphs.md
  • docs/problem-code-registry.json
  • docs/release/contract-first-gates.md
  • packages/cli/src/commands/generateUsageDashboard.ts
  • packages/cli/src/tests/generateUsageDashboard.spec.ts
  • packages/cli/src/tests/integration/e2e.spec.ts
  • packages/create-croco-app/src/tests/templates-build.spec.ts
  • packages/create-croco-app/templates/admin-console/README.md.hbs
  • packages/create-croco-app/templates/admin-console/apps/api-server/src/controllers/AdminController.ts
  • packages/create-croco-app/templates/admin-console/apps/api-server/src/controllers/adminSchemas.ts
  • packages/create-croco-app/templates/admin-console/package.json.hbs
  • packages/create-croco-app/templates/ai-saas/README.md.hbs
  • packages/create-croco-app/templates/ai-saas/apps/api-server/src/controllers/AiController.ts
  • packages/create-croco-app/templates/ai-saas/apps/api-server/src/controllers/aiSchemas.ts
  • packages/create-croco-app/templates/ai-saas/package.json.hbs
  • packages/create-croco-app/templates/saas/README.md.hbs
  • packages/create-croco-app/templates/saas/apps/api-server/src/controllers/JobsController.ts
  • packages/create-croco-app/templates/saas/apps/api-server/src/controllers/OperationsController.ts
  • packages/create-croco-app/templates/saas/apps/api-server/src/controllers/SaasController.ts
  • packages/create-croco-app/templates/saas/apps/api-server/src/controllers/schemas.ts
  • packages/create-croco-app/templates/saas/package.json.hbs
  • packages/create-croco-app/templates/spa-be-split/README.md.hbs
  • packages/create-croco-app/templates/spa-be-split/apps/api-server/src/controllers/UserController.ts
  • packages/create-croco-app/templates/spa-be-split/apps/api-server/src/controllers/userSchemas.ts
  • packages/create-croco-app/templates/spa-be-split/package.json.hbs
  • packages/docs/src/content/docs/api/problems-core/src/variables/CROCO_PROBLEM_CODE_REGISTRY.md
  • packages/docs/src/content/docs/api/protocols-core/src/functions/createContractGraphV1.md
  • packages/docs/src/content/docs/api/protocols-core/src/functions/createProjectManifestBundleArtifactPaths.md
  • packages/docs/src/content/docs/api/protocols-core/src/functions/isContractGraphV1.md
  • packages/docs/src/content/docs/api/protocols-core/src/functions/joinProjectManifestBundlePath.md
  • packages/docs/src/content/docs/api/protocols-core/src/functions/normalizeProjectManifestBundlePath.md
  • packages/docs/src/content/docs/api/protocols-core/src/functions/parseContractGraphStrictModeFlag.md
  • packages/docs/src/content/docs/api/protocols-core/src/functions/resolveContractGraphBlockingDiagnostics.md
  • packages/docs/src/content/docs/api/protocols-core/src/functions/stringifyContractGraphV1.md
  • packages/docs/src/content/docs/api/protocols-core/src/type-aliases/ContractGraphBlockingDiagnostics.md
  • packages/docs/src/content/docs/api/protocols-core/src/type-aliases/ContractGraphV1.md
  • packages/docs/src/content/docs/api/protocols-core/src/type-aliases/ContractGraphV1DiRef.md
  • packages/docs/src/content/docs/api/protocols-core/src/type-aliases/ContractGraphV1PolicyRef.md
  • packages/docs/src/content/docs/api/protocols-core/src/type-aliases/ContractGraphV1Route.md
  • packages/docs/src/content/docs/api/protocols-core/src/type-aliases/ContractGraphV1RuntimeRequirement.md
  • packages/docs/src/content/docs/api/protocols-core/src/type-aliases/ProjectManifestBundleArtifactFileName.md
  • packages/docs/src/content/docs/api/protocols-core/src/type-aliases/ProjectManifestBundleArtifactKey.md
  • packages/docs/src/content/docs/api/protocols-core/src/type-aliases/RouteContractIR.md
  • packages/docs/src/content/docs/api/protocols-core/src/variables/PROJECT_MANIFEST_BUNDLE_ARTIFACTS.md
  • packages/docs/src/content/docs/api/protocols-core/src/variables/PROJECT_MANIFEST_BUNDLE_ARTIFACT_ENTRIES.md
  • packages/docs/src/content/docs/en/reference/problem-recovery-cookbook.md
  • packages/openapi-spec/src/libs/cli.ts
  • packages/openapi-spec/src/tests/Cli.spec.ts
  • packages/protocols-core/src/index.ts
  • packages/protocols-core/src/libs/ContractGraph.ts
  • packages/protocols-core/src/libs/ContractGraphCli.ts
  • packages/protocols-core/src/libs/RouteIR.ts
  • packages/protocols-core/src/libs/extractRouteIR.ts
  • packages/protocols-core/src/libs/sharedTypes.ts
  • packages/protocols-core/src/tests/ContractGraph.spec.ts
  • packages/protocols-core/src/tests/extractRouteIR.spec.ts
  • packages/rpc-codegen/src/libs/cli.ts
  • packages/rpc-codegen/src/tests/Cli.spec.ts
  • packages/rpc-codegen/src/tests/ContractCheckCli.spec.ts
  • packages/rpc-codegen/src/tests/codegen.spec.ts
  • public-api-surface.snapshot.json
  • scripts/create-croco-app-generated-smoke.mts
  • scripts/problem-registry.mts
  • scripts/tests/problem-registry.spec.ts
📝 Walkthrough

Walkthrough

이 PR은 생성된 앱 경로의 ContractGraph를 strict하게 검증하도록 바꾸고, openapi-spec/rpc-codegen CLI에 fail-on-diagnostics와 strict/compatibility 분기 처리를 추가했다. 생성 앱 템플릿의 컨트롤러와 라우트 계약, 문서, 스모크 테스트, 문제 레지스트리도 함께 갱신됐다.

Changes

Contract Graph 코어 및 CLI Strict 모드

Layer / File(s) Summary
RouteContractIR problemResponsesDeclared 도입
packages/protocols-core/src/libs/RouteIR.ts, packages/protocols-core/src/libs/extractRouteIR.ts, packages/protocols-core/src/libs/ContractGraph.ts, packages/protocols-core/src/tests/ContractGraph.spec.ts, packages/protocols-core/src/tests/extractRouteIR.spec.ts, packages/docs/src/content/docs/api/protocols-core/src/type-aliases/RouteContractIR.md
RouteContractIR에 problemResponsesDeclared가 추가되고, ContractGraph 검증과 관련 테스트/문서가 이 플래그를 기준으로 갱신됨.
openapi-spec CLI strict/compatibility 옵션
packages/openapi-spec/src/libs/cli.ts, packages/openapi-spec/src/tests/Cli.spec.ts
failOnDiagnostics, strict/compatibility 조합 검증, 차단 진단 계산, 도움말 및 테스트가 갱신됨.
rpc-codegen CLI strict/compatibility 옵션
packages/rpc-codegen/src/libs/cli.ts, packages/rpc-codegen/src/tests/Cli.spec.ts, packages/rpc-codegen/src/tests/ContractCheckCli.spec.ts, packages/rpc-codegen/src/tests/codegen.spec.ts
동일한 strict/compatibility/fail-on-diagnostics 처리가 rpc-codegen에 반영되고 관련 테스트가 확장됨.

생성 앱 템플릿의 라우트 계약 전환

Layer / File(s) Summary
admin-console 라우트 계약화
packages/create-croco-app/templates/admin-console/apps/api-server/src/controllers/adminSchemas.ts, packages/create-croco-app/templates/admin-console/apps/api-server/src/controllers/AdminController.ts, packages/create-croco-app/templates/admin-console/package.json.hbs, packages/create-croco-app/templates/admin-console/README.md.hbs, docs/problem-code-registry.json, packages/docs/src/content/docs/en/reference/problem-recovery-cookbook.md, packages/create-croco-app/src/tests/templates-build.spec.ts
adminSchemas와 AdminController가 라우트 상수/문제 응답 기반으로 전환되고, 스크립트·문서·테스트가 갱신됨.
ai-saas 라우트 계약화
packages/create-croco-app/templates/ai-saas/apps/api-server/src/controllers/aiSchemas.ts, packages/create-croco-app/templates/ai-saas/apps/api-server/src/controllers/AiController.ts, packages/create-croco-app/templates/ai-saas/package.json.hbs, packages/create-croco-app/templates/ai-saas/README.md.hbs
aiSchemas와 AiController가 라우트 계약 기반으로 전환되고, 생성 스크립트와 문서가 갱신됨.
saas 템플릿 라우트 계약화
packages/create-croco-app/templates/saas/apps/api-server/src/controllers/schemas.ts, packages/create-croco-app/templates/saas/apps/api-server/src/controllers/JobsController.ts, packages/create-croco-app/templates/saas/apps/api-server/src/controllers/OperationsController.ts, packages/create-croco-app/templates/saas/apps/api-server/src/controllers/SaasController.ts, packages/create-croco-app/templates/saas/package.json.hbs, packages/create-croco-app/templates/saas/README.md.hbs, packages/create-croco-app/src/tests/templates-build.spec.ts
SaaS 라우트 계약과 컨트롤러가 계약 기반 데코레이터와 타입으로 전환되고, 스크립트·문서·구조 테스트가 갱신됨.
spa-be-split 라우트 계약 problems 필드
packages/create-croco-app/templates/spa-be-split/apps/api-server/src/controllers/userSchemas.ts, packages/create-croco-app/templates/spa-be-split/apps/api-server/src/controllers/UserController.ts, packages/create-croco-app/templates/spa-be-split/package.json.hbs, packages/create-croco-app/templates/spa-be-split/README.md.hbs
userSchemas에 problems가 추가되고 UserController가 ProblemResponses를 연결하며, 스크립트와 문서가 갱신됨.
CLI 생성 UsageDashboard 라우트 계약화
packages/cli/src/commands/generateUsageDashboard.ts, packages/cli/src/tests/generateUsageDashboard.spec.ts, packages/cli/src/tests/integration/e2e.spec.ts, scripts/static-misuse-raw-error-allowlist.json
UsageDashboard 템플릿이 라우트 계약 기반으로 전환되고, 응답 처리와 테스트, allowlist가 갱신됨.
문서 및 생성 앱 스모크 스크립트 갱신
.changeset/strict-generated-contract-graphs.md, docs/release/contract-first-gates.md, scripts/create-croco-app-generated-smoke.mts
strict 검증 기본 동작과 실패 조건을 설명하는 문서가 갱신되고, 스모크 스크립트가 strict 실패와 누락 아티팩트를 검증함.

Problem Registry Route Projection 처리

Layer / File(s) Summary
route projection 후보 필터링
scripts/problem-registry.mts, scripts/tests/problem-registry.spec.ts
defineRouteProblem 기반 route projection 후보를 별도 플래그로 추적하고, 기존 구현과 중복되는 후보를 제외하도록 발견 로직과 테스트가 변경됨.

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

Sequence Diagram(s)

sequenceDiagram
  participant Developer
  participant CLI as croco-openapi-spec / croco-rpc-codegen
  participant Graph as ContractGraph
  participant Output as OpenAPI / RPC artifacts
  Developer->>CLI: run with strict / compatibility flags
  CLI->>Graph: build and validate graph
  Graph-->>CLI: diagnostics or errors
  alt blocking diagnostics present
    CLI-->>Developer: exit 1, print diagnostics
  else no blocking diagnostics
    CLI->>Output: generate artifacts
    Output-->>Developer: files written
  end
Loading
sequenceDiagram
  participant Template as create-croco-app template
  participant Controller as generated controller
  participant Script as contract script
  participant Smoke as generated smoke test
  Template->>Controller: emit route contracts and problem responses
  Template->>Script: add --fail-on-diagnostics
  Smoke->>Script: run strict generation
  Script-->>Smoke: fail on diagnostics or emit artifacts
Loading

Possibly related PRs

  • croco-dev/framework#815: fail-on-diagnostics, strict ContractGraph validation, and problemResponsesDeclared 기반 검증이 같은 계약 검증 흐름을 확장합니다.
  • croco-dev/framework#819: create-croco-app SaaS 템플릿 계약 스크립트 갱신과 같은 템플릿 경로를 다룹니다.
  • croco-dev/framework#1118: openapi-spec CLI의 ContractGraph 검증과 check-mode 흐름을 직접 다룹니다.
🚥 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 제목이 strict generated contract graphs라는 핵심 변경을 간결하게 요약합니다.
Linked Issues check ✅ Passed 생성 1.0 앱 경로의 strict ContractGraph 검증, diagnostics 실패, compatibility opt-out, 문서화가 모두 반영되었습니다.
Out of Scope Changes check ✅ Passed 변경은 계약 그래프 엄격화와 관련 문서·템플릿·테스트 범위에 머물며 뚜렷한 무관 변경은 보이지 않습니다.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/1184-strict-contract-graph

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: 8dd8a25c79

ℹ️ 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".

Comment thread packages/protocols-core/src/libs/extractRouteIR.ts
@github-actions

github-actions Bot commented Jul 4, 2026

Copy link
Copy Markdown

📊 Benchmark Results

✅ All benchmarks passed

Benchmark p75 Threshold Baseline vs Baseline Status Notes
CrocoApp constructor 7.5μs 30.0ms 8.2μs -8.8% -
CrocoApp lambdaHandler (10 controllers) 278.6μs 50.0ms 258.4μs +7.8% -
Lambda cold-start simulation 446.1μs 80.0ms 418.1μs +6.7% -
Lambda cold-start with headers 372.8μs 80.0ms 369.7μs +0.8% -
Lambda cold-start with binary body 341.6μs 80.0ms 339.1μs +0.7% -
Lambda cold-start with query params 301.8μs 80.0ms 301.3μs +0.2% -
Lambda cold-start with authorizer context 301.4μs 80.0ms 299.8μs +0.5% -
Lambda cold-start realistic scenario 297.6μs 80.0ms 299.2μs -0.5% -
EventBusConfig.start (10 handlers) 1.4μs 10.0ms 1.4μs -4.2% -
EventPublisher.publishNow single event 1.7μs 2.0ms 1.7μs -1.8% -
DefaultHandlerResolver.resolve × 10 0.1μs 5.0ms 0.1μs -11.2% -
Container.get singleton (cold) 70.3μs 5.0ms 70.3μs +0.0% -
Container.register × 50 components 3.3ms 10.0ms 3.2ms +2.3% -
Container.validate (50 components) 3.5ms 20.0ms 3.4ms +3.9% -
Container.get singleton (warm) 1.6μs 500.0μs 1.6μs -1.8% -
TelemetryRuntime.init (lambda preset) 1.9μs 200.0ms 1.1ms -99.8% -
lambdaPreset config creation 1.4μs 2.0ms 1.4μs -2.0% -

Updated: 2026-07-05T09:01:07.604Z · Commit: aa26891

@kang-heewon
kang-heewon force-pushed the fix/1184-strict-contract-graph branch from 8dd8a25 to 78aa981 Compare July 4, 2026 16:43

@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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
packages/openapi-spec/src/libs/cli.ts (1)

101-149: 📐 Maintainability & Code Quality | 🟠 Major | ⚡ Quick win

parseStrictProblems/parseStrictSchemas/reportContractGraph 로직이 rpc-codegen CLI와 완전히 중복됩니다.

packages/rpc-codegen/src/libs/cli.ts의 145-166, 213-233 라인과 이 파일의 로직이 문구(에러 메시지 문자열)를 제외하고 사실상 동일합니다. strict/compatibility 판정 및 diagnostics 차단 로직은 이번 PR의 핵심 게이트인데, 두 패키지 모두 이미 @croco/protocols-core를 참조하고 있으므로 공통 헬퍼로 추출하면 향후 두 구현이 서로 다르게 발전(drift)하는 위험을 없앨 수 있습니다.

♻️ 제안: 공통 헬퍼를 protocols-core로 추출
+// packages/protocols-core/src/libs/cliStrictMode.ts
+export function parseStrictModeFlag(
+  args: readonly string[],
+  strictFlag: string,
+  compatibilityFlag: string,
+): boolean | null {
+  const strict = args.includes(strictFlag);
+  const compatibility = args.includes(compatibilityFlag);
+  if (strict && compatibility) {
+    return null;
+  }
+  return !compatibility;
+}
+
+export function resolveBlockingDiagnostics(
+  graph: ContractGraph,
+  failOnDiagnostics: boolean,
+): readonly ContractDiagnostic[] {
+  return failOnDiagnostics ? graph.diagnostics : getContractGraphErrors(graph);
+}

각 CLI에서는 다음과 같이 호출:

-function parseStrictProblems(args: readonly string[]): boolean | null {
-  const strictProblems = args.includes("--strict-problems");
-  const compatibilityProblems = args.includes("--compatibility-problems");
-  if (strictProblems && compatibilityProblems) {
-    return null;
-  }
-  return !compatibilityProblems;
-}
+const strictProblems = parseStrictModeFlag(args, "--strict-problems", "--compatibility-problems");

Also applies to: 217-237

🤖 Prompt for 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.

In `@packages/openapi-spec/src/libs/cli.ts` around lines 101 - 149, The
strict/compatibility parsing and diagnostics gating logic in the CLI is
duplicated with rpc-codegen, so extract the shared behavior into a common helper
in `@croco/protocols-core` and have the CLI use that instead. Refactor the
parseStrictProblems and parseStrictSchemas flow, along with the
reportContractGraph-related diagnostics check, to call the shared helper so both
packages stay in sync while preserving the existing CLI-specific error messages.
🤖 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/templates/ai-saas/apps/api-server/src/controllers/aiSchemas.ts`:
- Around line 1-12: The import block in aiSchemas should follow the project’s
ordering rules: external packages first, then internal `@croco/`* packages, then
relative imports, with type imports separated when applicable. Reorder the
imports in this file so zod is grouped with external dependencies before
`@croco/problems-core` and `@croco/protocols-rest`, while keeping the aiProblems
relative import last.

In
`@packages/create-croco-app/templates/spa-be-split/apps/api-server/src/controllers/userSchemas.ts`:
- Around line 1-4: The import order in the userSchemas module is out of
guideline order because the external package import for zod is placed after
internal `@croco/`* imports. Reorder the imports in userSchemas so they follow
external packages first, then `@croco/`* packages, then relative paths, and keep
any type-only imports in their own section if applicable. Use the existing
import block in userSchemas as the target to fix.

In `@packages/create-croco-app/templates/spa-be-split/README.md.hbs`:
- Around line 48-49: The new README paragraph in the template is still written
in English, breaking the document’s Korean language consistency. Translate the
added ContractGraph/OpenAPI/RPC explanation into Korean in the README template,
keeping the same meaning about strict schema checks, `--fail-on-diagnostics`,
and the `--compatibility-*` migration-only opt-outs.

---

Outside diff comments:
In `@packages/openapi-spec/src/libs/cli.ts`:
- Around line 101-149: The strict/compatibility parsing and diagnostics gating
logic in the CLI is duplicated with rpc-codegen, so extract the shared behavior
into a common helper in `@croco/protocols-core` and have the CLI use that instead.
Refactor the parseStrictProblems and parseStrictSchemas flow, along with the
reportContractGraph-related diagnostics check, to call the shared helper so both
packages stay in sync while preserving the existing CLI-specific error messages.
🪄 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: 27668cf4-df7c-4cc7-8d35-e65a66142710

📥 Commits

Reviewing files that changed from the base of the PR and between 47a4fd9 and 78aa981.

⛔ Files ignored due to path filters (1)
  • packages/problems-core/src/generated/problem-code-registry.ts is excluded by !**/generated/**
📒 Files selected for processing (41)
  • .changeset/strict-generated-contract-graphs.md
  • docs/problem-code-registry.json
  • docs/release/contract-first-gates.md
  • packages/cli/src/commands/generateUsageDashboard.ts
  • packages/cli/src/tests/generateUsageDashboard.spec.ts
  • packages/cli/src/tests/integration/e2e.spec.ts
  • packages/create-croco-app/src/tests/templates-build.spec.ts
  • packages/create-croco-app/templates/admin-console/README.md.hbs
  • packages/create-croco-app/templates/admin-console/apps/api-server/src/controllers/AdminController.ts
  • packages/create-croco-app/templates/admin-console/apps/api-server/src/controllers/adminSchemas.ts
  • packages/create-croco-app/templates/admin-console/package.json.hbs
  • packages/create-croco-app/templates/ai-saas/README.md.hbs
  • packages/create-croco-app/templates/ai-saas/apps/api-server/src/controllers/AiController.ts
  • packages/create-croco-app/templates/ai-saas/apps/api-server/src/controllers/aiSchemas.ts
  • packages/create-croco-app/templates/ai-saas/package.json.hbs
  • packages/create-croco-app/templates/saas/README.md.hbs
  • packages/create-croco-app/templates/saas/apps/api-server/src/controllers/JobsController.ts
  • packages/create-croco-app/templates/saas/apps/api-server/src/controllers/OperationsController.ts
  • packages/create-croco-app/templates/saas/apps/api-server/src/controllers/SaasController.ts
  • packages/create-croco-app/templates/saas/apps/api-server/src/controllers/schemas.ts
  • packages/create-croco-app/templates/saas/package.json.hbs
  • packages/create-croco-app/templates/spa-be-split/README.md.hbs
  • packages/create-croco-app/templates/spa-be-split/apps/api-server/src/controllers/UserController.ts
  • packages/create-croco-app/templates/spa-be-split/apps/api-server/src/controllers/userSchemas.ts
  • packages/create-croco-app/templates/spa-be-split/package.json.hbs
  • packages/docs/src/content/docs/en/reference/problem-recovery-cookbook.md
  • packages/openapi-spec/src/libs/cli.ts
  • packages/openapi-spec/src/tests/Cli.spec.ts
  • packages/protocols-core/src/libs/ContractGraph.ts
  • packages/protocols-core/src/libs/RouteIR.ts
  • packages/protocols-core/src/libs/extractRouteIR.ts
  • packages/protocols-core/src/tests/ContractGraph.spec.ts
  • packages/protocols-core/src/tests/extractRouteIR.spec.ts
  • packages/rpc-codegen/src/libs/cli.ts
  • packages/rpc-codegen/src/tests/Cli.spec.ts
  • packages/rpc-codegen/src/tests/ContractCheckCli.spec.ts
  • packages/rpc-codegen/src/tests/codegen.spec.ts
  • scripts/create-croco-app-generated-smoke.mts
  • scripts/problem-registry.mts
  • scripts/static-misuse-raw-error-allowlist.json
  • scripts/tests/problem-registry.spec.ts
💤 Files with no reviewable changes (1)
  • scripts/static-misuse-raw-error-allowlist.json

Comment thread packages/create-croco-app/templates/spa-be-split/README.md.hbs Outdated
@kang-heewon
kang-heewon force-pushed the fix/1184-strict-contract-graph branch 2 times, most recently from 925b8a0 to 4a51127 Compare July 4, 2026 17:50

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

🤖 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 73-75: The tests for generateUsageDashboard only assert that
certain strings exist, so they do not verify the real route produced by
combining `@Controller` with `@Get`(usageDashboardSnapshotRoute) and the contract
path. Update the generateUsageDashboard.spec.ts assertions to validate the
resolved controller route behavior for generateUsageDashboard.ts, using the
unique symbols usageDashboardSnapshotRoute and controllerContent, so the test
catches duplicate or conflicting route configurations instead of just matching
substrings.

In
`@packages/create-croco-app/templates/admin-console/apps/api-server/src/controllers/AdminController.ts`:
- Around line 25-62: The controller handlers are missing explicit RouteResponse
return types, so the route response contract is no longer checked at compile
time. Update AdminController methods like snapshot, listUsers, getUser,
createUser, and listOperations to return Promise<RouteResponse<typeof ...Route>>
and import RouteResponse alongside RouteBody/RouteParam/RouteQueryParam. Keep
the same pattern used in UserController so each handler’s service result is
validated against its route definition.

In
`@packages/create-croco-app/templates/saas/apps/api-server/src/controllers/schemas.ts`:
- Around line 1-3: The import ordering in the schema module is out of guideline:
`zod` should be grouped before the internal `@croco/*` imports. Update the
import block in `schemas.ts` (and mirror the same ordering pattern in
`userSchemas.ts` where applicable) so external packages like `zod` come first,
followed by `@croco/problems-core` and `@croco/protocols-rest`, keeping imports
organized consistently with the project import rules.

In `@packages/openapi-spec/src/libs/cli.ts`:
- Around line 62-77: There is duplicated blocking-diagnostics selection logic in
runCli and reportContractGraph, both combining getContractGraphErrors with
failOnDiagnostics to decide which diagnostics are blocking. Extract that shared
computation into a common helper and have both call sites use it, so the
blockingDiagnostics selection and related message logic live in one place. Use
the existing runCli, reportContractGraph, getContractGraphErrors, and
failOnDiagnostics symbols to centralize the behavior without changing the CLI
output.

In `@packages/protocols-core/src/libs/ContractGraph.ts`:
- Around line 798-805: The duplicate diagnostics issue in
validateRouteContractProblemResponses comes from iterating
route.routeContract.problemResponses directly when problemResponsesDeclared is
true, which allows repeated code values to generate repeated missing/mismatch
results. Update the ContractGraph route contract validation path to deduplicate
problem responses by code even for declared contracts, either by applying the
same code-based unique filtering used by getRouteContractProblemResponses or by
reusing that deduped helper before building diagnostics.

In `@packages/rpc-codegen/src/libs/cli.ts`:
- Around line 54-69: The blocking-diagnostics calculation and message selection
are duplicated between runCli and reportContractGraph, so consolidate this logic
into a shared helper used by both paths. Extract the error vs diagnostic
selection and the corresponding stdout message into a single function or
utility, then call it from runCli and reportContractGraph so --check and normal
generation always use the same blocking criteria and wording.
- Around line 145-166: The strict/compatibility parsing logic in
parseStrictProblems, parseStrictSchemas, and reportContractGraph is duplicated
across the CLI helpers, so extract the shared strict/compatibility handling into
a common cli-kit utility and reuse it from the CLI modules. Keep the existing
semantics intact for default strict behavior and the opt-out flags, and make
sure both packages import the same helper instead of maintaining separate
copies.
🪄 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: d05a8e30-427f-4e08-a3bf-a5bc439b8f81

📥 Commits

Reviewing files that changed from the base of the PR and between 78aa981 and 4a51127.

⛔ Files ignored due to path filters (1)
  • packages/problems-core/src/generated/problem-code-registry.ts is excluded by !**/generated/**
📒 Files selected for processing (43)
  • .changeset/strict-generated-contract-graphs.md
  • docs/problem-code-registry.json
  • docs/release/contract-first-gates.md
  • packages/cli/src/commands/generateUsageDashboard.ts
  • packages/cli/src/tests/generateUsageDashboard.spec.ts
  • packages/cli/src/tests/integration/e2e.spec.ts
  • packages/create-croco-app/src/tests/templates-build.spec.ts
  • packages/create-croco-app/templates/admin-console/README.md.hbs
  • packages/create-croco-app/templates/admin-console/apps/api-server/src/controllers/AdminController.ts
  • packages/create-croco-app/templates/admin-console/apps/api-server/src/controllers/adminSchemas.ts
  • packages/create-croco-app/templates/admin-console/package.json.hbs
  • packages/create-croco-app/templates/ai-saas/README.md.hbs
  • packages/create-croco-app/templates/ai-saas/apps/api-server/src/controllers/AiController.ts
  • packages/create-croco-app/templates/ai-saas/apps/api-server/src/controllers/aiSchemas.ts
  • packages/create-croco-app/templates/ai-saas/package.json.hbs
  • packages/create-croco-app/templates/saas/README.md.hbs
  • packages/create-croco-app/templates/saas/apps/api-server/src/controllers/JobsController.ts
  • packages/create-croco-app/templates/saas/apps/api-server/src/controllers/OperationsController.ts
  • packages/create-croco-app/templates/saas/apps/api-server/src/controllers/SaasController.ts
  • packages/create-croco-app/templates/saas/apps/api-server/src/controllers/schemas.ts
  • packages/create-croco-app/templates/saas/package.json.hbs
  • packages/create-croco-app/templates/spa-be-split/README.md.hbs
  • packages/create-croco-app/templates/spa-be-split/apps/api-server/src/controllers/UserController.ts
  • packages/create-croco-app/templates/spa-be-split/apps/api-server/src/controllers/userSchemas.ts
  • packages/create-croco-app/templates/spa-be-split/package.json.hbs
  • packages/docs/src/content/docs/api/problems-core/src/variables/CROCO_PROBLEM_CODE_REGISTRY.md
  • packages/docs/src/content/docs/api/protocols-core/src/type-aliases/RouteContractIR.md
  • packages/docs/src/content/docs/en/reference/problem-recovery-cookbook.md
  • packages/openapi-spec/src/libs/cli.ts
  • packages/openapi-spec/src/tests/Cli.spec.ts
  • packages/protocols-core/src/libs/ContractGraph.ts
  • packages/protocols-core/src/libs/RouteIR.ts
  • packages/protocols-core/src/libs/extractRouteIR.ts
  • packages/protocols-core/src/tests/ContractGraph.spec.ts
  • packages/protocols-core/src/tests/extractRouteIR.spec.ts
  • packages/rpc-codegen/src/libs/cli.ts
  • packages/rpc-codegen/src/tests/Cli.spec.ts
  • packages/rpc-codegen/src/tests/ContractCheckCli.spec.ts
  • packages/rpc-codegen/src/tests/codegen.spec.ts
  • scripts/create-croco-app-generated-smoke.mts
  • scripts/problem-registry.mts
  • scripts/static-misuse-raw-error-allowlist.json
  • scripts/tests/problem-registry.spec.ts

Comment thread packages/cli/src/tests/generateUsageDashboard.spec.ts Outdated
Comment thread packages/openapi-spec/src/libs/cli.ts
Comment thread packages/protocols-core/src/libs/ContractGraph.ts
Comment thread packages/rpc-codegen/src/libs/cli.ts
Comment thread packages/rpc-codegen/src/libs/cli.ts
@kang-heewon
kang-heewon force-pushed the fix/1184-strict-contract-graph branch 2 times, most recently from 2e0f673 to 1270ad9 Compare July 5, 2026 07:53
@kang-heewon
kang-heewon force-pushed the fix/1184-strict-contract-graph branch from 1270ad9 to ea214a0 Compare July 5, 2026 08:53
@kang-heewon
kang-heewon merged commit fa8eea4 into trunk Jul 5, 2026
8 of 9 checks passed
@kang-heewon
kang-heewon deleted the fix/1184-strict-contract-graph branch July 5, 2026 09:39
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.

[protocols-core] Make strict ContractGraph mode mandatory for generated 1.0 app paths

1 participant