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 managementprojects.*- Project CRUD operationsorganizations.*- Organization managementanalysis.*- Repository analysishealth- Health check
🔐 auth Router
Authentication, session management, and user profiles.
auth.getSession
Get current user session information.
Type: Query (public)
Input: None
Output:
{
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:
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:
{
id: string
email: string
name: string
avatar?: string
emailVerified: boolean
createdAt: Date
updatedAt: Date
}
Example:
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:
{
name?: string
avatar?: string // URL
}
Output: Updated user object
Example:
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:
Array<{
id: string
userId: string
expiresAt: Date
createdAt: Date
ipAddress?: string
userAgent?: string
}>
Example:
const { data: sessions } = await trpc.auth.listSessions.useQuery()
auth.invalidateSession
Logout (revoke current session).
Type: Mutation (protected)
Input: None
Output:
{ success: boolean }
Example:
const { mutate: logout } = trpc.auth.invalidateSession.useMutation()
logout()
auth.revokeSession
Revoke a specific session.
Type: Mutation (protected)
Input:
{
sessionToken: string
}
Output:
{ success: boolean }
Example:
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:
{ success: boolean }
Example:
const { mutate } = trpc.auth.revokeOtherSessions.useMutation()
mutate()
auth.getAuditLogs
Get authentication audit logs for current user.
Type: Query (protected)
Input:
{
limit?: number // 1-100, default: 50
offset?: number // default: 0
}
Output:
Array<{
id: string
userId: string
action: string
ipAddress?: string
userAgent?: string
metadata?: Record<string, any>
createdAt: Date
}>
Example:
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:
{
userEmail: string // email format
}
Output:
{
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:
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:
{
projectId: string
userEmail: string
}
Output:
{
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:
const { data } = await trpc.projects.getProject.useQuery({
projectId: 'proj_123',
userEmail: 'user@example.com'
})
Errors:
User not foundProject not found- Project doesn't exist or user doesn't own it
projects.createProject
Create a new project.
Type: Mutation (protected)
Input:
{
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:
{
project: {
id: string
name: string
repository: string
// ... other fields
testRuns: []
}
}
Example:
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 foundProject 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:
{
projectId: string
userEmail: string
name?: string
description?: string
branch?: string
language?: string
framework?: string
}
Output:
{
project: {
// Updated project with settings and testRuns
}
}
Example:
const { mutate } = trpc.projects.updateProject.useMutation()
mutate({
projectId: 'proj_123',
userEmail: 'user@example.com',
name: 'Updated Name',
description: 'New description'
})
Errors:
User not foundProject not found
Note: Cannot update id, repository, userId, or createdAt
projects.deleteProject
Delete a project and all associated data.
Type: Mutation (protected)
Input:
{
projectId: string
userEmail: string
}
Output:
{
message: 'Project deleted successfully'
}
Example:
const { mutate } = trpc.projects.deleteProject.useMutation()
mutate({
projectId: 'proj_123',
userEmail: 'user@example.com'
})
Errors:
User not foundProject 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:
{
projectId: string
userEmail: string
}
Output:
{
analyses: Array<{
id: string
projectId: string
repoUrl: string
branch: string
commitSha?: string
analysis: object // Full analysis JSONB
createdAt: Date
}>
}
Example:
const { data } = await trpc.projects.getProjectAnalyses.useQuery({
projectId: 'proj_123',
userEmail: 'user@example.com'
})
Errors:
User not foundProject not found or access denied
projects.getLatestProjectAnalysis
Get most recent analysis for a project.
Type: Query (protected)
Input:
{
projectId: string
userEmail: string
}
Output:
{
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:
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:
{
userEmail: string
}
Output:
{
organizations: Array<{
id: string
name: string
slug: string
description?: string
role: 'OWNER' | 'ADMIN' | 'MEMBER' | 'VIEWER'
createdAt: Date
updatedAt: Date
}>
}
Example:
const { data } = await trpc.organizations.list.useQuery({
userEmail: 'user@example.com'
})
organizations.create
Create a new organization.
Type: Mutation (protected)
Input:
{
name: string // min 1 char
slug: string // lowercase, numbers, hyphens only
userEmail: string
description?: string
}
Output:
{
organization: {
id: string
name: string
slug: string
description?: string
createdAt: Date
updatedAt: Date
}
}
Example:
const { mutate } = trpc.organizations.create.useMutation()
mutate({
name: 'Acme Corp',
slug: 'acme-corp',
userEmail: 'user@example.com',
description: 'Our organization'
})
Errors:
User not foundAn 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:
{
slug: string
userEmail: string
}
Output:
{
organization: {
id: string
name: string
slug: string
description?: string
role: 'OWNER' | 'ADMIN' | 'MEMBER' | 'VIEWER' // User's role
createdAt: Date
updatedAt: Date
}
}
Errors:
User not foundOrganization not foundAccess denied- User is not a member
organizations.delete
Delete an organization.
Type: Mutation (protected)
Input:
{
organizationId: string
userEmail: string
}
Output:
{
message: 'Organization deleted successfully'
}
Errors:
User not foundOnly 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:
{
organizationId: string
userEmail: string
}
Output:
{
members: Array<{
id: string // membership ID
userId: string
email: string
name: string
role: 'OWNER' | 'ADMIN' | 'MEMBER' | 'VIEWER'
createdAt: Date
}>
}
Example:
const { data } = await trpc.organizations.getMembers.useQuery({
organizationId: 'org_123',
userEmail: 'user@example.com'
})
Errors:
User not foundAccess denied- User is not a member
Permissions: Any member can view
organizations.inviteMember
Invite a user to join the organization.
Type: Mutation (protected)
Input:
{
organizationId: string
userEmail: string // Inviter
userToInviteEmail: string // Invitee
role?: 'OWNER' | 'ADMIN' | 'MEMBER' | 'VIEWER' // default: 'MEMBER'
}
Output:
{
member: {
id: string
organizationId: string
userId: string
email: string
name: string
role: string
createdAt: Date
}
}
Example:
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 membersUser 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:
{
organizationId: string
membershipId: string
userEmail: string
newRole: 'OWNER' | 'ADMIN' | 'MEMBER' | 'VIEWER'
}
Output:
{
member: {
id: string
role: string
// ... other fields
}
}
Errors:
User not foundOnly organization owners can change member rolesCannot remove the last owner of an organizationCannot change your own role(prevents lockout)
Permissions: OWNER only
organizations.removeMember
Remove a member from the organization.
Type: Mutation (protected)
Input:
{
organizationId: string
membershipId: string
userEmail: string
}
Output:
{
message: 'Member removed successfully'
}
Errors:
User not foundOnly organization owners and admins can remove membersMember not foundCannot 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:
{
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:
{
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:
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 foundProject not found or access deniedAnalysis 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:
{ ok: true }
Example:
const { data } = await trpc.health.useQuery()
// { ok: true }
🔧 Type Inference
TypeScript types are automatically inferred from the router:
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:
// 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 issueProject not found- Resource doesn't exist or no accessAccess denied- Insufficient permissionsOnly organization owners can...- Permission denied- Validation errors from Zod schemas
See Error Codes for complete reference.
🔗 Related Documentation
- Authentication API - Auth flows and session management
- REST Endpoints - Non-tRPC endpoints
- Types Reference - TypeScript types and schemas
- Error Codes - Error handling guide
- tRPC Package - Implementation details