# tRPC Routers API Reference

Complete API reference for all tRPC routers in the Izri platform.

## 📋 Overview

The tRPC API provides type-safe client-server communication with automatic TypeScript inference. All endpoints require authentication unless marked as `publicProcedure`.

**Base URL**: `/trpc`

**Router Structure**:

- `auth.*` - Authentication & session management
- `projects.*` - Project CRUD operations
- `organizations.*` - Organization management
- `analysis.*` - Repository analysis
- `health` - Health check

---

## 🔐 auth Router

Authentication, session management, and user profiles.

### auth.getSession

Get current user session information.

**Type**: Query (public)

**Input**: None

**Output**:

```typescript
{
  isAuthenticated: boolean
  session: {
    id: string
    userId: string
    expiresAt: Date
    createdAt: Date
  } | null
  user: {
    id: string
    email: string
    name: string
    avatar?: string
    createdAt: Date
  } | null
}
```

**Example**:

```typescript
const { data } = await trpc.auth.getSession.useQuery()
if (data?.isAuthenticated) {
  console.log('Logged in as:', data.user?.email)
}
```

---

### auth.getProfile

Get current user profile details.

**Type**: Query (protected)

**Input**: None

**Output**:

```typescript
{
  id: string
  email: string
  name: string
  avatar?: string
  emailVerified: boolean
  createdAt: Date
  updatedAt: Date
}
```

**Example**:

```typescript
const { data: profile } = await trpc.auth.getProfile.useQuery()
```

**Errors**:

- `User not authenticated` - No active session

---

### auth.updateProfile

Update current user's profile information.

**Type**: Mutation (protected)

**Input**:

```typescript
{
  name?: string
  avatar?: string  // URL
}
```

**Output**: Updated user object

**Example**:

```typescript
const { mutate } = trpc.auth.updateProfile.useMutation()
mutate({
  name: 'John Doe',
  avatar: 'https://example.com/avatar.jpg'
})
```

---

### auth.listSessions

List all active sessions for current user.

**Type**: Query (protected)

**Input**: None

**Output**:

```typescript
Array<{
  id: string
  userId: string
  expiresAt: Date
  createdAt: Date
  ipAddress?: string
  userAgent?: string
}>
```

**Example**:

```typescript
const { data: sessions } = await trpc.auth.listSessions.useQuery()
```

---

### auth.invalidateSession

Logout (revoke current session).

**Type**: Mutation (protected)

**Input**: None

**Output**:

```typescript
{ success: boolean }
```

**Example**:

```typescript
const { mutate: logout } = trpc.auth.invalidateSession.useMutation()
logout()
```

---

### auth.revokeSession

Revoke a specific session.

**Type**: Mutation (protected)

**Input**:

```typescript
{
  sessionToken: string
}
```

**Output**:

```typescript
{ success: boolean }
```

**Example**:

```typescript
const { mutate } = trpc.auth.revokeSession.useMutation()
mutate({ sessionToken: 'session_abc123' })
```

---

### auth.revokeOtherSessions

Revoke all sessions except the current one.

**Type**: Mutation (protected)

**Input**: None

**Output**:

```typescript
{ success: boolean }
```

**Example**:

```typescript
const { mutate } = trpc.auth.revokeOtherSessions.useMutation()
mutate()
```

---

### auth.getAuditLogs

Get authentication audit logs for current user.

**Type**: Query (protected)

**Input**:

```typescript
{
  limit?: number   // 1-100, default: 50
  offset?: number  // default: 0
}
```

**Output**:

```typescript
Array<{
  id: string
  userId: string
  action: string
  ipAddress?: string
  userAgent?: string
  metadata?: Record<string, any>
  createdAt: Date
}>
```

**Example**:

```typescript
const { data: logs } = await trpc.auth.getAuditLogs.useQuery({
  limit: 20,
  offset: 0
})
```

---

## 📁 projects Router

Project management and CRUD operations.

### projects.getProjects

Get all projects for current user.

**Type**: Query (public)

**Input**:

```typescript
{
  userEmail: string  // email format
}
```

**Output**:

```typescript
{
  projects: Array<{
    id: string
    name: string
    description?: string
    repository: string
    branch: string
    language: string
    framework?: string
    userId: string
    createdAt: Date
    updatedAt: Date
    testRuns: Array<{
      id: string
      projectId: string
      status: 'pending' | 'running' | 'completed' | 'failed'
      totalTests: number
      passedTests: number
      failedTests: number
      createdAt: Date
    }>
  }>
}
```

**Example**:

```typescript
const { data } = await trpc.projects.getProjects.useQuery({
  userEmail: 'user@example.com'
})
```

**Errors**:

- `User not found` - Email doesn't match any user

---

### projects.getProject

Get single project by ID with test runs and settings.

**Type**: Query (protected)

**Input**:

```typescript
{
  projectId: string
  userEmail: string
}
```

**Output**:

```typescript
{
  project: {
    id: string
    name: string
    description?: string
    repository: string
    branch: string
    language: string
    framework?: string
    userId: string
    createdAt: Date
    updatedAt: Date
    testRuns: TestRun[]
    settings: {
      id: string
      projectId: string
      autoRunTests: boolean
      enableUnitTests: boolean
      enableIntegrationTests: boolean
      enableE2ETests: boolean
      notifyOnFailure: boolean
    } | null
  }
}
```

**Example**:

```typescript
const { data } = await trpc.projects.getProject.useQuery({
  projectId: 'proj_123',
  userEmail: 'user@example.com'
})
```

**Errors**:

- `User not found`
- `Project not found` - Project doesn't exist or user doesn't own it

---

### projects.createProject

Create a new project.

**Type**: Mutation (protected)

**Input**:

```typescript
{
  name: string             // min 1 char
  repository: string       // min 1 char
  userEmail: string        // email format
  description?: string
  branch?: string          // default: 'main'
  language?: string        // default: 'unknown'
  framework?: string
}
```

**Output**:

```typescript
{
  project: {
    id: string
    name: string
    repository: string
    // ... other fields
    testRuns: []
  }
}
```

**Example**:

```typescript
const { mutate } = trpc.projects.createProject.useMutation()
mutate({
  name: 'My App',
  repository: 'https://github.com/user/repo',
  userEmail: 'user@example.com',
  branch: 'main',
  language: 'typescript',
  framework: 'react'
})
```

**Errors**:

- `User not found`
- `Project with this repository already exists` - Duplicate repository URL for user

**Side Effects**:

- Creates default project settings
- Sets `autoRunTests: false`, `notifyOnFailure: true`, enables all test types

---

### projects.updateProject

Update existing project.

**Type**: Mutation (protected)

**Input**:

```typescript
{
  projectId: string
  userEmail: string
  name?: string
  description?: string
  branch?: string
  language?: string
  framework?: string
}
```

**Output**:

```typescript
{
  project: {
    // Updated project with settings and testRuns
  }
}
```

**Example**:

```typescript
const { mutate } = trpc.projects.updateProject.useMutation()
mutate({
  projectId: 'proj_123',
  userEmail: 'user@example.com',
  name: 'Updated Name',
  description: 'New description'
})
```

**Errors**:

- `User not found`
- `Project not found`

**Note**: Cannot update `id`, `repository`, `userId`, or `createdAt`

---

### projects.deleteProject

Delete a project and all associated data.

**Type**: Mutation (protected)

**Input**:

```typescript
{
  projectId: string
  userEmail: string
}
```

**Output**:

```typescript
{
  message: 'Project deleted successfully'
}
```

**Example**:

```typescript
const { mutate } = trpc.projects.deleteProject.useMutation()
mutate({
  projectId: 'proj_123',
  userEmail: 'user@example.com'
})
```

**Errors**:

- `User not found`
- `Project not found`

**Side Effects** (Cascade):

- Deletes project settings
- Deletes all test runs
- Deletes all analyses
- **Cannot be undone**

---

### projects.getProjectAnalyses

Get all analyses for a project.

**Type**: Query (protected)

**Input**:

```typescript
{
  projectId: string
  userEmail: string
}
```

**Output**:

```typescript
{
  analyses: Array<{
    id: string
    projectId: string
    repoUrl: string
    branch: string
    commitSha?: string
    analysis: object  // Full analysis JSONB
    createdAt: Date
  }>
}
```

**Example**:

```typescript
const { data } = await trpc.projects.getProjectAnalyses.useQuery({
  projectId: 'proj_123',
  userEmail: 'user@example.com'
})
```

**Errors**:

- `User not found`
- `Project not found or access denied`

---

### projects.getLatestProjectAnalysis

Get most recent analysis for a project.

**Type**: Query (protected)

**Input**:

```typescript
{
  projectId: string
  userEmail: string
}
```

**Output**:

```typescript
{
  analysis: {
    id: string
    projectId: string
    repoUrl: string
    branch: string
    commitSha?: string
    analysis: {
      files: Array<{
        path: string
        language: string
        size: number
        content?: string
      }>
      languages: Record<string, number>
      frameworks: string[]
      dependencies: Record<string, string>
      // ... full analysis structure
    }
    createdAt: Date
  } | null
}
```

**Example**:

```typescript
const { data } = await trpc.projects.getLatestProjectAnalysis.useQuery({
  projectId: 'proj_123',
  userEmail: 'user@example.com'
})
```

---

## 🏢 organizations Router

Multi-tenancy and organization management.

### organizations.list

List all organizations for current user.

**Type**: Query (protected)

**Input**:

```typescript
{
  userEmail: string
}
```

**Output**:

```typescript
{
  organizations: Array<{
    id: string
    name: string
    slug: string
    description?: string
    role: 'OWNER' | 'ADMIN' | 'MEMBER' | 'VIEWER'
    createdAt: Date
    updatedAt: Date
  }>
}
```

**Example**:

```typescript
const { data } = await trpc.organizations.list.useQuery({
  userEmail: 'user@example.com'
})
```

---

### organizations.create

Create a new organization.

**Type**: Mutation (protected)

**Input**:

```typescript
{
  name: string           // min 1 char
  slug: string           // lowercase, numbers, hyphens only
  userEmail: string
  description?: string
}
```

**Output**:

```typescript
{
  organization: {
    id: string
    name: string
    slug: string
    description?: string
    createdAt: Date
    updatedAt: Date
  }
}
```

**Example**:

```typescript
const { mutate } = trpc.organizations.create.useMutation()
mutate({
  name: 'Acme Corp',
  slug: 'acme-corp',
  userEmail: 'user@example.com',
  description: 'Our organization'
})
```

**Errors**:

- `User not found`
- `An organization with this slug already exists`
- Validation error if slug format is invalid

**Side Effects**:

- Creator automatically becomes OWNER
- Slug must be globally unique

---

### organizations.getBySlug

Get organization details by slug.

**Type**: Query (protected)

**Input**:

```typescript
{
  slug: string
  userEmail: string
}
```

**Output**:

```typescript
{
  organization: {
    id: string
    name: string
    slug: string
    description?: string
    role: 'OWNER' | 'ADMIN' | 'MEMBER' | 'VIEWER'  // User's role
    createdAt: Date
    updatedAt: Date
  }
}
```

**Errors**:

- `User not found`
- `Organization not found`
- `Access denied` - User is not a member

---

### organizations.delete

Delete an organization.

**Type**: Mutation (protected)

**Input**:

```typescript
{
  organizationId: string
  userEmail: string
}
```

**Output**:

```typescript
{
  message: 'Organization deleted successfully'
}
```

**Errors**:

- `User not found`
- `Only organization owners can delete organizations`

**Permissions**: OWNER only

**Side Effects**:

- Deletes all members (cascade)
- **Cannot be undone**

---

### organizations.getMembers

List all members of an organization.

**Type**: Query (protected)

**Input**:

```typescript
{
  organizationId: string
  userEmail: string
}
```

**Output**:

```typescript
{
  members: Array<{
    id: string           // membership ID
    userId: string
    email: string
    name: string
    role: 'OWNER' | 'ADMIN' | 'MEMBER' | 'VIEWER'
    createdAt: Date
  }>
}
```

**Example**:

```typescript
const { data } = await trpc.organizations.getMembers.useQuery({
  organizationId: 'org_123',
  userEmail: 'user@example.com'
})
```

**Errors**:

- `User not found`
- `Access denied` - User is not a member

**Permissions**: Any member can view

---

### organizations.inviteMember

Invite a user to join the organization.

**Type**: Mutation (protected)

**Input**:

```typescript
{
  organizationId: string
  userEmail: string              // Inviter
  userToInviteEmail: string      // Invitee
  role?: 'OWNER' | 'ADMIN' | 'MEMBER' | 'VIEWER'  // default: 'MEMBER'
}
```

**Output**:

```typescript
{
  member: {
    id: string
    organizationId: string
    userId: string
    email: string
    name: string
    role: string
    createdAt: Date
  }
}
```

**Example**:

```typescript
const { mutate } = trpc.organizations.inviteMember.useMutation()
mutate({
  organizationId: 'org_123',
  userEmail: 'admin@example.com',
  userToInviteEmail: 'newuser@example.com',
  role: 'MEMBER'
})
```

**Errors**:

- `User not found` (inviter or invitee)
- `Only organization owners and admins can invite members`
- `User is already a member of this organization`

**Permissions**: OWNER and ADMIN

---

### organizations.updateMemberRole

Change a member's role in the organization.

**Type**: Mutation (protected)

**Input**:

```typescript
{
  organizationId: string
  membershipId: string
  userEmail: string
  newRole: 'OWNER' | 'ADMIN' | 'MEMBER' | 'VIEWER'
}
```

**Output**:

```typescript
{
  member: {
    id: string
    role: string
    // ... other fields
  }
}
```

**Errors**:

- `User not found`
- `Only organization owners can change member roles`
- `Cannot remove the last owner of an organization`
- `Cannot change your own role` (prevents lockout)

**Permissions**: OWNER only

---

### organizations.removeMember

Remove a member from the organization.

**Type**: Mutation (protected)

**Input**:

```typescript
{
  organizationId: string
  membershipId: string
  userEmail: string
}
```

**Output**:

```typescript
{
  message: 'Member removed successfully'
}
```

**Errors**:

- `User not found`
- `Only organization owners and admins can remove members`
- `Member not found`
- `Cannot remove the last owner of an organization`

**Permissions**: OWNER and ADMIN

**Side Effects**:

- Removes access to all organization projects
- User can be re-invited later

---

## 🔬 analysis Router

Repository analysis operations.

### analysis.analyzeRepository

Analyze a GitHub repository and store results.

**Type**: Mutation (protected)

**Input**:

```typescript
{
  projectId: string
  repoUrl: string              // GitHub URL
  userEmail: string
  branch?: string              // default: 'main'
  githubToken?: string         // For private repos
  options?: {
    maxFiles?: number          // default: 1000
    maxFileSizeBytes?: number  // default: 500KB
    includeHashes?: boolean    // default: false
  }
}
```

**Output**:

```typescript
{
  success: boolean
  message: string
  analysis: {
    id: string
    projectId: string
    repoUrl: string
    branch: string
    commitSha?: string
    analysis: {
      files: Array<{
        path: string
        language: string
        size: number
        extension: string
        hash?: string
        content?: string
      }>
      languages: Record<string, number>  // { "TypeScript": 150, "JavaScript": 50 }
      frameworks: string[]               // ["react", "vite"]
      dependencies: Record<string, string>
      testFiles: string[]
      testCandidates: Array<{
        path: string
        priority: number
        reason: string
      }>
      structure: {
        directories: number
        files: number
        totalSize: number
      }
      commitSha: string
      analyzedAt: string
    }
    createdAt: Date
  }
}
```

**Example**:

```typescript
const { mutate, isLoading } = trpc.analysis.analyzeRepository.useMutation()
mutate({
  projectId: 'proj_123',
  repoUrl: 'https://github.com/user/repo',
  userEmail: 'user@example.com',
  branch: 'main',
  options: {
    maxFiles: 500,
    includeHashes: true
  }
})
```

**Errors**:

- `User not found`
- `Project not found or access denied`
- `Analysis failed: <error message>` - Repository clone/parse errors

**Side Effects**:

- Clones repository to temporary directory
- Analyzes file structure, languages, frameworks
- Stores analysis in database (upserts by projectId + commitSha)
- Cleans up temporary files

**Performance**:

- Large repositories may take 10-60 seconds
- Consider running in background job for very large repos

---

## 🏥 health

Simple health check endpoint.

**Type**: Query (public)

**Input**: None

**Output**:

```typescript
{ ok: true }
```

**Example**:

```typescript
const { data } = await trpc.health.useQuery()
// { ok: true }
```

---

## 🔧 Type Inference

TypeScript types are automatically inferred from the router:

```typescript
import type { AppRouter, AppRouterInputs, AppRouterOutputs } from '@izri/trpc'

// Input types
type CreateProjectInput = AppRouterInputs['projects']['createProject']
type GetProjectInput = AppRouterInputs['projects']['getProject']

// Output types
type ProjectsOutput = AppRouterOutputs['projects']['getProjects']
type SessionOutput = AppRouterOutputs['auth']['getSession']

// Router type for custom hooks
type Router = AppRouter
```

---

## 🚨 Error Handling

All errors are thrown as `TRPCError` with descriptive messages:

```typescript
// Client-side error handling
const { mutate } = trpc.projects.createProject.useMutation({
  onError: (error) => {
    console.error(error.message)
    // "User not found"
    // "Project with this repository already exists"
  },
  onSuccess: (data) => {
    console.log('Project created:', data.project.id)
  }
})
```

Common error messages:

- `User not found` - Authentication/authorization issue
- `Project not found` - Resource doesn't exist or no access
- `Access denied` - Insufficient permissions
- `Only organization owners can...` - Permission denied
- Validation errors from Zod schemas

See [Error Codes](./error-codes.md) for complete reference.

---

## 🔗 Related Documentation

- [Authentication API](./authentication-api.md) - Auth flows and session management
- [REST Endpoints](./rest-endpoints.md) - Non-tRPC endpoints
- [Types Reference](./types.md) - TypeScript types and schemas
- [Error Codes](./error-codes.md) - Error handling guide
- [tRPC Package](../packages/trpc-package.md) - Implementation details
