Problem
RouteContract 타입은 path param/schema mismatch를 build-time에 잡을 수 있지만, 실제 generated app과 일반 controller 작성 경로는 여전히 @Get, @Param, @Body, @ResponseSchema를 따로 조합한다. 이 조합은 path, params, body, response가 서로 drift되어도 타입 시스템이 단일 계약으로 묶어 주지 못한다.
Evidence
packages/protocols-rest/src/libs/types/RouteContract.ts:101-105는 defineRouteContract를 제공한다.
- 같은 파일
:145-178은 route path와 params schema mismatch를 타입 수준에서 검증한다.
packages/create-croco-app/templates/spa-be-split/apps/api-server/src/controllers/UserController.ts:24-53는 @Get, @Param, @Body, @ResponseSchema를 독립적으로 작성한다.
- 이 구조에서는 route path 변경, param 이름 변경, response schema 변경이 하나의 compile-time source of truth로 묶이지 않는다.
Desired Outcome
REST route 작성자가 하나의 typed RouteContract를 선언하고, 데코레이터/parameter binding/response schema/client generation이 그 계약을 소비하도록 한다. 잘못된 path param, 빠진 body schema, 잘못된 response type은 controller 구현 시점에 typecheck 또는 contract check에서 실패해야 한다.
Proposed Implementation Path
RouteContract를 controller decorator path에서 직접 소비하는 API를 추가한다. 예: @Route(contract) 또는 @Get(contract) 계열 overload.
@Param, @Query, @Body, @ResponseSchema가 contract helper에서 schema/name을 가져오도록 helper를 제공한다.
- 기존 decorator 조합은 compatibility path로 유지하되 generated app template과 docs는 contract-first API로 전환한다.
RouteContractTypes.spec.ts에 controller/decorator 사용 예시까지 포함한 @ts-expect-error fixture를 추가한다.
- ContractGraph가 route contract id/source location을 보존해 OpenAPI/RPC diagnostics와 연결되게 한다.
Acceptance Criteria
- generated REST template의 주요 route가 typed
RouteContract를 source of truth로 사용한다.
- path에 있는
:id와 params schema key가 다르면 pnpm typecheck에서 실패하는 fixture가 있다.
- body/response schema가 contract와 다르게 연결되면 type-level 또는 contract diagnostic으로 실패한다.
- RPC/OpenAPI output은 contract-first route와 기존 decorator route를 모두 처리한다.
- migration guide가 기존 loose decorator 조합에서 contract-first 조합으로 옮기는 최소 예시를 제공한다.
Validation
pnpm test --filter=@croco/protocols-rest
pnpm test --filter=@croco/protocols-core
pnpm test --filter=@croco/rpc-codegen
pnpm test --filter=@croco/openapi-spec
pnpm create-croco-app:smoke
Scope Boundaries
- 이번 이슈는 REST route contract 작성 경험에 집중한다.
- GraphQL/tRPC 계약 API 재설계는 별도 이슈로 둔다.
Problem
RouteContract타입은 path param/schema mismatch를 build-time에 잡을 수 있지만, 실제 generated app과 일반 controller 작성 경로는 여전히@Get,@Param,@Body,@ResponseSchema를 따로 조합한다. 이 조합은 path, params, body, response가 서로 drift되어도 타입 시스템이 단일 계약으로 묶어 주지 못한다.Evidence
packages/protocols-rest/src/libs/types/RouteContract.ts:101-105는defineRouteContract를 제공한다.:145-178은 route path와 params schema mismatch를 타입 수준에서 검증한다.packages/create-croco-app/templates/spa-be-split/apps/api-server/src/controllers/UserController.ts:24-53는@Get,@Param,@Body,@ResponseSchema를 독립적으로 작성한다.Desired Outcome
REST route 작성자가 하나의 typed
RouteContract를 선언하고, 데코레이터/parameter binding/response schema/client generation이 그 계약을 소비하도록 한다. 잘못된 path param, 빠진 body schema, 잘못된 response type은 controller 구현 시점에 typecheck 또는 contract check에서 실패해야 한다.Proposed Implementation Path
RouteContract를 controller decorator path에서 직접 소비하는 API를 추가한다. 예:@Route(contract)또는@Get(contract)계열 overload.@Param,@Query,@Body,@ResponseSchema가 contract helper에서 schema/name을 가져오도록 helper를 제공한다.RouteContractTypes.spec.ts에 controller/decorator 사용 예시까지 포함한@ts-expect-errorfixture를 추가한다.Acceptance Criteria
RouteContract를 source of truth로 사용한다.:id와 params schema key가 다르면pnpm typecheck에서 실패하는 fixture가 있다.Validation
pnpm test --filter=@croco/protocols-restpnpm test --filter=@croco/protocols-corepnpm test --filter=@croco/rpc-codegenpnpm test --filter=@croco/openapi-specpnpm create-croco-app:smokeScope Boundaries