npm package: @solomonai/trpc-clerk
Description: A comprehensive tRPC implementation for the Solomon AI Financial Workspace Platform, providing type-safe API endpoints with middleware support for authentication, authorization, rate limiting, and tier-based resource limits.
Latest version: 0.0.0

# @solomonai/trpc

A comprehensive tRPC implementation for the Solomon AI Financial Workspace Platform, providing type-safe API endpoints with middleware support for authentication, authorization, rate limiting, and tier-based resource limits.

## Overview

This package serves as the backbone for all API communication in the Solomon AI platform, using tRPC to provide end-to-end type safety between the client and server. It includes a robust middleware system for enforcing security, resource limits, and team-based authorization.

## Features

- **Type-Safe API**: End-to-end type safety between client and server
- **Authentication**: Middleware for handling user authentication and API key validation
- **Team Authorization**: Comprehensive team membership and role-based access control
- **Tier Limits**: Integration with the pricing package to enforce subscription-based resource limits
- **Rate Limiting**: Protection against API abuse with configurable rate limits
- **OpenAPI Integration**: Automatic OpenAPI schema generation for API documentation

## Directory Structure

```
trpc/
├── src/
│   ├── adapters/           # Adapters for various integrations
│   ├── auth/               # Authentication related functionality
│   ├── context.ts          # tRPC context definition
│   ├── middlewares/        # Middleware implementations
│   │   ├── apiKeyMiddleware.ts           # API key validation
│   │   ├── authorizationMiddleware.ts    # General authorization
│   │   ├── loggedInMiddleware.ts         # User authentication
│   │   ├── procedures.ts                 # Procedure definitions
│   │   ├── ratelimitMiddleware.ts        # Rate limiting
│   │   ├── teamAuthorizationMiddleware.ts # Team-based authorization
│   │   └── tierLimitsMiddleware.ts       # Subscription tier limits
│   ├── openapi/            # OpenAPI schema generation
│   ├── ratelimit/          # Rate limiting implementation
│   ├── routers/            # API route definitions
│   ├── trpc-client/        # Client-side tRPC setup
│   ├── trpc.ts             # Core tRPC initialization
│   └── types.ts            # Type definitions
```

## Usage

### Basic Router Setup

```typescript
import { createRouter, publicProcedure } from '@solomonai/trpc'
import { z } from 'zod'

export const exampleRouter = createRouter({
  hello: publicProcedure
    .input(z.object({ name: z.string() }))
    .query(({ input }) => {
      return {
        greeting: `Hello ${input.name}!`,
      }
    }),
})
```

### Protected Routes with Authentication

```typescript
import { createRouter } from '@solomonai/trpc'
import { protectedProcedure } from '@solomonai/trpc/middlewares/procedures'
import { z } from 'zod'

export const userRouter = createRouter({
  getProfile: protectedProcedure
    .query(({ ctx }) => {
      // ctx.userId is guaranteed to exist
      return {
        user: ctx.user,
      }
    }),
})
```

### Team Authorization

```typescript
import { createRouter } from '@solomonai/trpc'
import { isTeamMember, isTeamOwner } from '@solomonai/trpc/middlewares/teamAuthorizationMiddleware'
import { protectedProcedure } from '@solomonai/trpc/middlewares/procedures'
import { z } from 'zod'

export const teamRouter = createRouter({
  // Only team members can access this route
  getTeamDetails: protectedProcedure
    .use(isTeamMember)
    .input(z.object({ teamId: z.string() }))
    .query(({ ctx }) => {
      // ctx.teamMembership is guaranteed to exist
      return {
        team: ctx.team,
        role: ctx.teamMembership.role,
      }
    }),

  // Only team owners can access this route
  updateTeamSettings: protectedProcedure
    .use(isTeamOwner)
    .input(z.object({ 
      teamId: z.string(),
      settings: z.object({
        name: z.string().optional(),
        // other settings...
      })
    }))
    .mutation(({ ctx, input }) => {
      // Only team owners can reach this point
      // Implementation...
    }),
})
```

### Resource Limits Based on Subscription Tier

```typescript
import { createRouter } from '@solomonai/trpc'
import { protectedProcedure } from '@solomonai/trpc/middlewares/procedures'
import { tierLimitsMiddleware, LimitableResourceEnum } from '@solomonai/trpc/middlewares/tierLimitsMiddleware'
import { z } from 'zod'

export const documentsRouter = createRouter({
  createDocument: protectedProcedure
    .use(
      tierLimitsMiddleware({
        resource: LimitableResourceEnum.Documents,
        errorMessage: 'You have reached the maximum number of documents for your plan',
      })
    )
    .input(z.object({ 
      title: z.string(),
      content: z.string() 
    }))
    .mutation(({ ctx, input }) => {
      // User has not reached their document limit
      // Implementation...
    }),
})
```

### Convenience Procedures with Tier Limits

```typescript
import { createRouter } from '@solomonai/trpc'
import { 
  createLimitedProcedure, 
  createTeamLimitedProcedure 
} from '@solomonai/trpc/middlewares/procedures'
import { LimitableResourceEnum } from '@solomonai/trpc/middlewares/tierLimitsMiddleware'
import { z } from 'zod'

export const invoicesRouter = createRouter({
  // User-level resource with tier limits
  createInvoice: createLimitedProcedure({
    resource: LimitableResourceEnum.Invoices,
    errorMessage: 'Invoice limit reached for your plan',
  })
    .input(z.object({ /* invoice data */ }))
    .mutation(({ ctx, input }) => {
      // Implementation...
    }),

  // Team-level resource with tier limits
  createTeamInvoice: createTeamLimitedProcedure({
    resource: LimitableResourceEnum.Invoices,
    errorMessage: 'Team invoice limit reached for your plan',
  })
    .input(z.object({ 
      teamId: z.string(),
      /* invoice data */ 
    }))
    .mutation(({ ctx, input }) => {
      // Implementation...
    }),
})
```

## Client Usage

```typescript
// In your client code
import { trpc } from '@solomonai/trpc/client'

// Type-safe API calls
const greeting = await trpc.example.hello.query({ name: 'World' })
console.log(greeting.greeting) // "Hello World!"
```

## License

[MIT](LICENSE)