oRPC Contract-First Development Project Structure web/contract/ ├── base.ts # Base contract (inputStructure: 'detailed') ├── router.ts # Router composition & type exports ├── marketplace.ts # Marketplace contracts └── console/ # Console contracts by domain ├── system.ts └── billing.ts
Workflow
Create contract in web/contract/console/{domain}.ts
Import base from ../base and type from @orpc/contract Define route with path, method, input, output
Register in router at web/contract/router.ts
Import directly from domain file (no barrel files) Nest by API prefix: billing: { invoices, bindPartnerStack }
Create hooks in web/service/use-{domain}.ts
Use consoleQuery.{group}.{contract}.queryKey() for query keys
Use consoleClient.{group}.{contract}() for API calls
Key Rules
Input structure: Always use { params, query?, body? } format
Path params: Use {paramName} in path, match in params object
Router nesting: Group by API prefix (e.g., /billing/* → billing: {})
No barrel files: Import directly from specific files
Types: Import from @/types/, use type