Skip to content

fix: enforce Croco lifecycle policies for tRPC procedures - #1734

Merged
kang-heewon merged 8 commits into
trunkfrom
issue-1674-trpc-execution-pipeline
Aug 4, 2026
Merged

fix: enforce Croco lifecycle policies for tRPC procedures#1734
kang-heewon merged 8 commits into
trunkfrom
issue-1674-trpc-execution-pipeline

Conversation

@kang-heewon

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

Copy link
Copy Markdown
Member

Fixes #1674

Outcome

tRPC procedures now enter Croco's lifecycle pipeline before input parsing, so declared guards can deny a call before validation or handler execution. Class and method interceptors wrap controller invocation, while filters process guard, validation, interceptor, and handler failures in documented order.

Declared Problems and RFC 7807 filter results carry stable Croco code and status details through tRPC while private details and extensions stay redacted from wire messages and development stack data. Applications can provide their container through TrpcRouterOptions for controller and lifecycle-provider resolution.

Review focus

  • The tRPC adapter reuses REST lifecycle metadata without importing an HTTP transport.
  • tRPC can only encode error semantics: filter results must be 4xx/5xx RFC 7807 Problem Details. Other response shapes preserve the original failure and record CROCO_TRPC_FILTER_001.

Verification

  • pnpm --filter @croco/protocols-trpc test — 13 tests passed.
  • pnpm --filter @croco/protocols-trpc typecheck
  • pnpm --filter @croco/protocols-trpc lint
  • pnpm --filter @croco/protocols-trpc build
  • pnpm public-api:check
  • pnpm docs:api:check
  • Pre-push hook: full repository tests and typecheck passed.

Review gates

  • Correctness: exercised guard-before-input ordering, class/method lifecycle order, filter conversion, redacted network errors, and container-backed providers.
  • API/release: verified package dependencies, public API snapshot, generated API docs, and a patch changeset.
  • Maintainability: kept transport-independent execution and documented the filter response boundary.
  • Independent adversarial review: passed after addressing ordering, redaction, DI, filter-conversion, observability, and API-snapshot findings.

Summary by CodeRabbit

  • 새로운 기능

    • tRPC 라우터에서 가드, 인터셉터, 필터가 정의된 정책에 따라 실행됩니다.
    • 실행 컨텍스트와 컨테이너 기반 provider 조회를 지원합니다.
    • 요청 컨텍스트를 표준화하고, 오류를 Croco Problem Details 형식으로 제공합니다.
    • 민감한 정보가 제거된 오류 세부 정보와 접근 거부 오류 코드가 지원됩니다.
    • TrpcExecutionContext와 라우터 옵션을 공개 API로 제공합니다.
  • 문서

    • tRPC 실행 컨텍스트, 라우터 옵션 및 오류 처리 동작에 대한 API 문서가 추가·보강되었습니다.

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

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

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: c7791026-cc28-4a0b-9846-4672104f835c

📥 Commits

Reviewing files that changed from the base of the PR and between 64a5533 and c42057c.

⛔ Files ignored due to path filters (2)
  • packages/problems-core/src/generated/problem-code-registry.ts is excluded by !**/generated/**
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (14)
  • .changeset/protocols-trpc-execution-pipeline.md
  • docs/problem-code-registry.json
  • packages/docs/src/content/docs/api/protocols-trpc/src/classes/TrpcExecutionContext.md
  • packages/docs/src/content/docs/api/protocols-trpc/src/functions/createTrpcRouter.md
  • packages/docs/src/content/docs/api/protocols-trpc/src/type-aliases/TrpcRouterOptions.md
  • packages/docs/src/content/docs/en/reference/problem-recovery-cookbook.md
  • packages/protocols-trpc/package.json
  • packages/protocols-trpc/src/index.ts
  • packages/protocols-trpc/src/libs/TrpcExecutionContext.ts
  • packages/protocols-trpc/src/libs/TrpcExecutionPipeline.ts
  • packages/protocols-trpc/src/libs/TrpcProblemError.ts
  • packages/protocols-trpc/src/libs/createTrpcRouter.ts
  • packages/protocols-trpc/src/tests/TrpcExecutionPipeline.spec.ts
  • public-api-surface.snapshot.json
📝 Walkthrough

Walkthrough

tRPC 라우터가 Croco 실행 컨텍스트를 생성하고 가드, 인터셉터, 필터를 실행합니다. Problem은 redacted RFC 7807 형식의 tRPC 오류로 변환됩니다. 컨테이너 기반 provider 생성과 공개 API, 테스트, Problem 문서가 추가되었습니다.

Changes

tRPC 실행 파이프라인

Layer / File(s) Summary
실행 컨텍스트와 Problem 계약
packages/protocols-trpc/src/libs/TrpcExecutionContext.ts, packages/protocols-trpc/src/libs/TrpcProblemError.ts, packages/protocols-trpc/src/index.ts, public-api-surface.snapshot.json, packages/protocols-trpc/package.json
TrpcExecutionContext가 tRPC 컨텍스트와 실행 메타데이터를 제공합니다. 요청을 표준 Request로 정규화합니다. Problem을 redaction 정책에 따라 tRPC 상세 형식으로 변환합니다. 새 API를 공개 export합니다.
가드·인터셉터·필터 실행
packages/protocols-trpc/src/libs/TrpcExecutionPipeline.ts
가드를 순차 실행하고 인터셉터를 역순으로 중첩 실행합니다. 필터 결과와 HTTP 응답을 Problem으로 변환합니다. 필터 실패 진단 이벤트와 상태 코드별 tRPC 오류 매핑을 추가합니다.
라우터 연결과 provider 조회
packages/protocols-trpc/src/libs/createTrpcRouter.ts, packages/docs/src/content/docs/api/protocols-trpc/src/functions/createTrpcRouter.md, packages/docs/src/content/docs/api/protocols-trpc/src/type-aliases/TrpcRouterOptions.md
라우터가 실행 컨텍스트와 파이프라인을 사용합니다. 가드는 입력 파싱 전에 실행됩니다. 컨트롤러와 provider는 선택적 컨테이너에서 조회할 수 있습니다.
통합 검증과 Problem 문서
packages/protocols-trpc/src/tests/TrpcExecutionPipeline.spec.ts, docs/problem-code-registry.json, packages/docs/src/content/docs/en/reference/problem-recovery-cookbook.md, packages/docs/src/content/docs/api/protocols-trpc/src/classes/TrpcExecutionContext.md, .changeset/protocols-trpc-execution-pipeline.md
통합 테스트가 거부, 실행 순서, Problem 직렬화, 필터 진단, DI 및 요청 정규화를 검증합니다. 새 Problem 코드와 API 문서 및 patch changeset을 추가합니다.

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

Sequence Diagram(s)

sequenceDiagram
  participant Client as tRPC Client
  participant Router as createTrpcRouter
  participant Context as TrpcExecutionContext
  participant Pipeline as TrpcExecutionPipeline
  participant Guard as Croco Guard
  participant Interceptor as Croco Interceptor
  participant Handler as Route Handler
  participant Filter as Croco Exception Filter
  Client->>Router: procedure 요청
  Router->>Context: 실행 컨텍스트 생성
  Router->>Pipeline: 가드 실행
  Pipeline->>Guard: canActivate 호출
  Pipeline->>Interceptor: 인터셉터 체인 실행
  Interceptor->>Handler: route handler 호출
  Handler-->>Interceptor: 결과 또는 오류 반환
  Pipeline->>Filter: handler 오류 전달
  Filter-->>Router: Problem 또는 원래 오류 반환
  Router-->>Client: tRPC 오류 응답
Loading

Possibly related issues

Possibly related PRs

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 4.55% 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
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed 제목은 tRPC 프로시저에 Croco 라이프사이클 정책을 적용하는 주요 변경을 정확히 설명합니다.
Linked Issues check ✅ Passed 가드, 인터셉터, 필터, Problem 변환, 컨테이너 지원과 관련 통합 테스트가 이슈 #1674의 요구사항을 충족합니다.
Out of Scope Changes check ✅ Passed 구현, 테스트, 문서, 의존성, 공개 API, 문제 레지스트리 변경은 모두 tRPC 라이프사이클 파이프라인 목표와 관련됩니다.
✨ 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 issue-1674-trpc-execution-pipeline

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.

@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 43.4μs 30.0ms 8.2μs +430.7% -
CrocoApp lambdaHandler (10 controllers) 1.9ms 50.0ms 258.4μs +631.8% -
Lambda cold-start simulation 1.7ms 80.0ms 418.1μs +315.3% -
Lambda cold-start with headers 1.6ms 80.0ms 369.7μs +331.9% -
Lambda cold-start with binary body 1.6ms 80.0ms 339.1μs +359.2% -
Lambda cold-start with query params 1.6ms 80.0ms 301.3μs +419.2% -
Lambda cold-start with authorizer context 1.5ms 80.0ms 299.8μs +407.4% -
Lambda cold-start realistic scenario 1.5ms 80.0ms 299.2μs +402.8% -
EventBusConfig.start (10 handlers) 1.7μs 10.0ms 1.4μs +15.4% -
EventPublisher.publishNow single event 1.9μs 2.0ms 1.7μs +11.9% -
DefaultHandlerResolver.resolve × 10 0.1μs 5.0ms 0.1μs +0.0% -
Container.get singleton (cold) 89.8μs 5.0ms 70.3μs +27.9% -
Container.register × 50 components 3.4ms 10.0ms 3.2ms +4.4% -
Container.validate (50 components) 3.8ms 20.0ms 3.4ms +13.3% -
Container.get singleton (warm) 1.7μs 500.0μs 1.6μs +1.8% -
TelemetryRuntime.init (lambda preset) 2.3μs 200.0ms 1.1ms -99.8% -
lambdaPreset config creation 1.5μs 2.0ms 1.4μs +6.4% -

Updated: 2026-08-04T14:47:55.466Z · Commit: a1fd0e6

@kang-heewon
kang-heewon force-pushed the issue-1674-trpc-execution-pipeline branch from 7afb433 to 8bad615 Compare August 1, 2026 21:30

@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/protocols-trpc/src/index.ts`:
- Around line 2-3: Reorder the exports in the module so the value export
TrpcExecutionContext appears before the type export TrpcRouterOptions. Keep both
exports unchanged and place all type exports after the value exports.

In `@packages/protocols-trpc/src/libs/createTrpcRouter.ts`:
- Around line 107-120: Update createProcedure’s setup around
createGuardAndFilterConfig and createInterceptors to resolve getGuards,
getFilters, and getInterceptors once during procedure construction, then reuse
those provider lists per request. Keep instantiateProvider inside the
request-time paths so container-scoped instantiation behavior remains unchanged.
- Around line 184-192: Update instantiateProvider to inspect provider.length
when options.container is absent and immediately throw a clear diagnostic
Problem if the provider declares constructor parameters, rather than casting it
to a zero-argument constructor and calling it without arguments. Preserve
container-based instantiation and zero-argument provider creation unchanged.

In `@packages/protocols-trpc/src/libs/TrpcExecutionContext.ts`:
- Around line 6-12: Update TrpcExecutionContext to accept a TContext generic,
type its trpcContext constructor field as TContext, and make getTrpcContext()
return TContext instead of unknown. Preserve the existing execution-context
behavior while propagating the typed context through all relevant declarations.
- Around line 40-49: Update readRequest to validate context.request,
context.req, and context as actual Fetch Request instances before returning
them, rather than accepting arbitrary objects through casts. Explicitly
normalize supported Node request objects into a Fetch Request, and route
unconstructable or invalid inputs through the established failure path instead
of returning an unsafe Request cast.

In `@packages/protocols-trpc/src/libs/TrpcExecutionPipeline.ts`:
- Around line 80-128: Extend TrpcExecutionPipeline.spec.ts with coverage for
both runFilters failure paths: a filter returning a non-4xx/5xx or otherwise
invalid result must record a CROCO_TRPC_FILTER_001 diagnostic with reason
"invalid-return", and a filter throwing must record the same diagnostic with
reason "thrown". Mock or inspect the runtime inspector to verify the event, and
assert the client receives the original error unchanged in both cases.

In `@packages/protocols-trpc/src/libs/TrpcProblemError.ts`:
- Around line 38-52: Update createTrpcFilterProblem to accept only RFC 7807
details with 4xx or 5xx status codes, in addition to matching the requested
status. Return undefined for 2xx, 3xx, or any other out-of-range status before
constructing TrpcFilterProblem, preserving the existing catch behavior.

In `@packages/protocols-trpc/src/tests/TrpcExecutionPipeline.spec.ts`:
- Around line 202-208: Update all three async denial assertions in
TrpcExecutionPipeline.spec.ts—around the `caller.trpcDeny.denied()` checks at
the referenced cases—to additionally verify the rejected error with
`rejects.toThrow()` while preserving the existing `rejects.toMatchObject` checks
for `code`, `cause.code`, and `status`. Ensure both error-throwing behavior and
structural details remain validated.
🪄 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: ca98e6ad-dccf-4472-b8ca-a0ef2aea9f94

📥 Commits

Reviewing files that changed from the base of the PR and between cadc8b7 and 8bad615.

⛔ Files ignored due to path filters (2)
  • packages/problems-core/src/generated/problem-code-registry.ts is excluded by !**/generated/**
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (14)
  • .changeset/protocols-trpc-execution-pipeline.md
  • docs/problem-code-registry.json
  • packages/docs/src/content/docs/api/protocols-trpc/src/classes/TrpcExecutionContext.md
  • packages/docs/src/content/docs/api/protocols-trpc/src/functions/createTrpcRouter.md
  • packages/docs/src/content/docs/api/protocols-trpc/src/type-aliases/TrpcRouterOptions.md
  • packages/docs/src/content/docs/en/reference/problem-recovery-cookbook.md
  • packages/protocols-trpc/package.json
  • packages/protocols-trpc/src/index.ts
  • packages/protocols-trpc/src/libs/TrpcExecutionContext.ts
  • packages/protocols-trpc/src/libs/TrpcExecutionPipeline.ts
  • packages/protocols-trpc/src/libs/TrpcProblemError.ts
  • packages/protocols-trpc/src/libs/createTrpcRouter.ts
  • packages/protocols-trpc/src/tests/TrpcExecutionPipeline.spec.ts
  • public-api-surface.snapshot.json

Comment thread packages/protocols-trpc/src/index.ts Outdated
Comment thread packages/protocols-trpc/src/libs/createTrpcRouter.ts Outdated
Comment thread packages/protocols-trpc/src/libs/createTrpcRouter.ts
Comment thread packages/protocols-trpc/src/libs/TrpcExecutionContext.ts Outdated
Comment thread packages/protocols-trpc/src/libs/TrpcExecutionContext.ts Outdated
Comment thread packages/protocols-trpc/src/libs/TrpcExecutionPipeline.ts
Comment thread packages/protocols-trpc/src/libs/TrpcProblemError.ts
Comment thread packages/protocols-trpc/src/tests/TrpcExecutionPipeline.spec.ts Outdated
@kang-heewon
kang-heewon force-pushed the issue-1674-trpc-execution-pipeline branch from 1dd3bc0 to 3e15dca Compare August 1, 2026 22:01
@kang-heewon

Copy link
Copy Markdown
Member Author

@coderabbitai resolve

@coderabbitai

coderabbitai Bot commented Aug 1, 2026

Copy link
Copy Markdown
✅ Action performed

Comments resolved and changes approved.

@kang-heewon
kang-heewon force-pushed the issue-1674-trpc-execution-pipeline branch from 3e15dca to 64a5533 Compare August 2, 2026 01:17

@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/protocols-trpc/src/libs/createTrpcRouter.ts`:
- Around line 128-150: Move createGuardAndFilterConfig() into the try block in
lifecycleProcedure so guard provider instantiation failures are handled by
rethrowFiltered() alongside runGuards() failures. Keep the existing context
creation and downstream procedure-result filtering behavior unchanged.

In `@packages/protocols-trpc/src/libs/TrpcExecutionContext.ts`:
- Around line 101-102: Update normalizeNodeRequest() so failures creating
Headers, URL, or Request are not converted to undefined; instead return or
propagate a distinct normalization diagnostic with a stable diagnostic code and
private evidence containing the underlying cause. Update readRequest() to
distinguish this normalization failure from genuinely unavailable requests and
avoid exposing URL, headers, or other sensitive values in the response.

In `@packages/protocols-trpc/src/tests/TrpcExecutionPipeline.spec.ts`:
- Around line 233-238: Change the test setup hook in the “tRPC Croco execution
pipeline” suite from afterEach to beforeEach so Container.reset() runs before
every test; keep the existing event and observedTrpcContext cleanup in the
appropriate per-test setup.
🪄 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: a0c75207-ff15-4950-8904-748778cd4088

📥 Commits

Reviewing files that changed from the base of the PR and between 8bad615 and 64a5533.

⛔ Files ignored due to path filters (2)
  • packages/problems-core/src/generated/problem-code-registry.ts is excluded by !**/generated/**
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (14)
  • .changeset/protocols-trpc-execution-pipeline.md
  • docs/problem-code-registry.json
  • packages/docs/src/content/docs/api/protocols-trpc/src/classes/TrpcExecutionContext.md
  • packages/docs/src/content/docs/api/protocols-trpc/src/functions/createTrpcRouter.md
  • packages/docs/src/content/docs/api/protocols-trpc/src/type-aliases/TrpcRouterOptions.md
  • packages/docs/src/content/docs/en/reference/problem-recovery-cookbook.md
  • packages/protocols-trpc/package.json
  • packages/protocols-trpc/src/index.ts
  • packages/protocols-trpc/src/libs/TrpcExecutionContext.ts
  • packages/protocols-trpc/src/libs/TrpcExecutionPipeline.ts
  • packages/protocols-trpc/src/libs/TrpcProblemError.ts
  • packages/protocols-trpc/src/libs/createTrpcRouter.ts
  • packages/protocols-trpc/src/tests/TrpcExecutionPipeline.spec.ts
  • public-api-surface.snapshot.json

Comment thread packages/protocols-trpc/src/libs/createTrpcRouter.ts Outdated
Comment thread packages/protocols-trpc/src/libs/TrpcExecutionContext.ts Outdated
Comment thread packages/protocols-trpc/src/tests/TrpcExecutionPipeline.spec.ts
@kang-heewon

Copy link
Copy Markdown
Member Author

@coderabbitai resolve

@coderabbitai

coderabbitai Bot commented Aug 2, 2026

Copy link
Copy Markdown
✅ Action performed

Comments resolved and changes approved.

@kang-heewon
kang-heewon force-pushed the issue-1674-trpc-execution-pipeline branch 3 times, most recently from 9c51d04 to b371c22 Compare August 4, 2026 13:27
@kang-heewon
kang-heewon force-pushed the issue-1674-trpc-execution-pipeline branch from b371c22 to c42057c Compare August 4, 2026 14:36
@kang-heewon
kang-heewon merged commit 47b942b into trunk Aug 4, 2026
11 checks passed
@kang-heewon
kang-heewon deleted the issue-1674-trpc-execution-pipeline branch August 4, 2026 15:31
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-trpc] Execute Croco authorization and error pipeline for tRPC procedures

1 participant