# HRIStudio API Routes Documentation

## Overview

HRIStudio uses tRPC for type-safe API communication between client and server. All routes are organized into routers by feature area and composed into a single app router. Authentication is handled by NextAuth.js v5.

## Base Configuration

```typescript
// All routes are prefixed with /api/trpc/
// Example: POST /api/trpc/auth.login
```

## Authentication Routes (`auth`)

### `auth.login`
- **Description**: Authenticate user with email/password or OAuth
- **Type**: Mutation
- **Input**: 
  ```typescript
  {
    email?: string
    password?: string
    provider?: 'google' | 'github' | 'microsoft'
    callbackUrl?: string
  }
  ```
- **Output**: Session object with user details
- **Auth Required**: No
- **Notes**: Handled primarily by NextAuth.js

### `auth.logout`
- **Description**: End user session
- **Type**: Mutation
- **Input**: None
- **Output**: `{ success: boolean }`
- **Auth Required**: Yes

### `auth.register`
- **Description**: Create new user account
- **Type**: Mutation
- **Input**:
  ```typescript
  {
    email: string
    password: string
    name: string
    institution?: string
  }
  ```
- **Output**: User object
- **Auth Required**: No

### `auth.me`
- **Description**: Get current user profile
- **Type**: Query
- **Input**: None
- **Output**: User object with roles
- **Auth Required**: Yes

## User Management Routes (`users`)

### `users.list`
- **Description**: List all users (admin only)
- **Type**: Query
- **Input**:
  ```typescript
  {
    page?: number
    limit?: number
    search?: string
    role?: SystemRole
  }
  ```
- **Output**: Paginated user list
- **Auth Required**: Yes (Administrator)

### `users.get`
- **Description**: Get user by ID
- **Type**: Query
- **Input**: `{ id: string }`
- **Output**: User object
- **Auth Required**: Yes

### `users.update`
- **Description**: Update user profile
- **Type**: Mutation
- **Input**:
  ```typescript
  {
    id: string
    name?: string
    email?: string
    image?: string
  }
  ```
- **Output**: Updated user object
- **Auth Required**: Yes (Self or Administrator)

### `users.assignRole`
- **Description**: Assign system role to user
- **Type**: Mutation
- **Input**:
  ```typescript
  {
    userId: string
    role: SystemRole
  }
  ```
- **Output**: Updated user roles
- **Auth Required**: Yes (Administrator)

### `users.delete`
- **Description**: Soft delete user account
- **Type**: Mutation
- **Input**: `{ id: string }`
- **Output**: `{ success: boolean }`
- **Auth Required**: Yes (Administrator)

## Study Management Routes (`studies`)

### `studies.list`
- **Description**: List studies accessible to user
- **Type**: Query
- **Input**:
  ```typescript
  {
    page?: number
    limit?: number
    status?: StudyStatus
    search?: string
    myStudiesOnly?: boolean
  }
  ```
- **Output**: Paginated study list with member counts
- **Auth Required**: Yes

### `studies.get`
- **Description**: Get study details
- **Type**: Query
- **Input**: `{ id: string }`
- **Output**: Complete study object with metadata
- **Auth Required**: Yes (Study member)

### `studies.create`
- **Description**: Create new study
- **Type**: Mutation
- **Input**:
  ```typescript
  {
    name: string
    description?: string
    institution?: string
    irbProtocol?: string
    metadata?: Record<string, any>
  }
  ```
- **Output**: Created study object
- **Auth Required**: Yes (Researcher)

### `studies.update`
- **Description**: Update study details
- **Type**: Mutation
- **Input**:
  ```typescript
  {
    id: string
    name?: string
    description?: string
    status?: StudyStatus
    metadata?: Record<string, any>
    settings?: Record<string, any>
  }
  ```
- **Output**: Updated study object
- **Auth Required**: Yes (Study owner/researcher)

### `studies.delete`
- **Description**: Archive study (soft delete)
- **Type**: Mutation
- **Input**: `{ id: string }`
- **Output**: `{ success: boolean }`
- **Auth Required**: Yes (Study owner)

### `studies.addMember`
- **Description**: Add member to study team
- **Type**: Mutation
- **Input**:
  ```typescript
  {
    studyId: string
    userId: string
    role: StudyRole
    permissions?: string[]
  }
  ```
- **Output**: Study member object
- **Auth Required**: Yes (Study owner/researcher)

### `studies.removeMember`
- **Description**: Remove member from study
- **Type**: Mutation
- **Input**:
  ```typescript
  {
    studyId: string
    userId: string
  }
  ```
- **Output**: `{ success: boolean }`
- **Auth Required**: Yes (Study owner)

### `studies.getMembers`
- **Description**: List study team members
- **Type**: Query
- **Input**: `{ studyId: string }`
- **Output**: Array of member objects with roles
- **Auth Required**: Yes (Study member)

### `studies.getActivity`
- **Description**: Get study activity log
- **Type**: Query
- **Input**:
  ```typescript
  {
    studyId: string
    page?: number
    limit?: number
    startDate?: Date
    endDate?: Date
  }
  ```
- **Output**: Paginated activity log
- **Auth Required**: Yes (Study member)

## Experiment Design Routes (`experiments`)

### `experiments.list`
- **Description**: List experiments in a study
- **Type**: Query
- **Input**:
  ```typescript
  {
    studyId: string
    status?: ExperimentStatus
  }
  ```
- **Output**: Array of experiment objects
- **Auth Required**: Yes (Study member)

### `experiments.get`
- **Description**: Get experiment details with steps
- **Type**: Query
- **Input**: `{ id: string }`
- **Output**: Experiment object with nested steps and actions
- **Auth Required**: Yes (Study member)

### `experiments.create`
- **Description**: Create new experiment
- **Type**: Mutation
- **Input**:
  ```typescript
  {
    studyId: string
    name: string
    description?: string
    robotId?: string
    estimatedDuration?: number
    metadata?: Record<string, any>
  }
  ```
- **Output**: Created experiment object
- **Auth Required**: Yes (Study researcher)

### `experiments.update`
- **Description**: Update experiment details
- **Type**: Mutation
- **Input**:
  ```typescript
  {
    id: string
    name?: string
    description?: string
    status?: ExperimentStatus
    estimatedDuration?: number
    metadata?: Record<string, any>
  }
  ```
- **Output**: Updated experiment object
- **Auth Required**: Yes (Study researcher)

### `experiments.duplicate`
- **Description**: Create copy of experiment
- **Type**: Mutation
- **Input**:
  ```typescript
  {
    experimentId: string
    newName: string
    includeSteps?: boolean
  }
  ```
- **Output**: New experiment object
- **Auth Required**: Yes (Study researcher)

### `experiments.delete`
- **Description**: Delete experiment
- **Type**: Mutation
- **Input**: `{ id: string }`
- **Output**: `{ success: boolean }`
- **Auth Required**: Yes (Study researcher)

### `experiments.addStep`
- **Description**: Add step to experiment
- **Type**: Mutation
- **Input**:
  ```typescript
  {
    experimentId: string
    name: string
    description?: string
    type: StepType
    orderIndex: number
    durationEstimate?: number
    required?: boolean
    conditions?: Record<string, any>
  }
  ```
- **Output**: Created step object
- **Auth Required**: Yes (Study researcher)

### `experiments.updateStep`
- **Description**: Update step details
- **Type**: Mutation
- **Input**: Step object with id
- **Output**: Updated step object
- **Auth Required**: Yes (Study researcher)

### `experiments.deleteStep`
- **Description**: Remove step from experiment
- **Type**: Mutation
- **Input**: `{ id: string }`
- **Output**: `{ success: boolean }`
- **Auth Required**: Yes (Study researcher)

### `experiments.reorderSteps`
- **Description**: Change step order
- **Type**: Mutation
- **Input**:
  ```typescript
  {
    experimentId: string
    stepIds: string[] // in new order
  }
  ```
- **Output**: `{ success: boolean }`
- **Auth Required**: Yes (Study researcher)

### `experiments.addAction`
- **Description**: Add action to step
- **Type**: Mutation
- **Input**:
  ```typescript
  {
    stepId: string
    name: string
    description?: string
    type: string
    orderIndex: number
    parameters?: Record<string, any>
    validationSchema?: Record<string, any>
    timeout?: number
  }
  ```
- **Output**: Created action object
- **Auth Required**: Yes (Study researcher)

### `experiments.updateAction`
- **Description**: Update action details
- **Type**: Mutation
- **Input**: Action object with id
- **Output**: Updated action object
- **Auth Required**: Yes (Study researcher)

### `experiments.deleteAction`
- **Description**: Remove action from step
- **Type**: Mutation
- **Input**: `{ id: string }`
- **Output**: `{ success: boolean }`
- **Auth Required**: Yes (Study researcher)

### `experiments.validate`
- **Description**: Validate experiment configuration
- **Type**: Query
- **Input**: `{ experimentId: string }`
- **Output**:
  ```typescript
  {
    valid: boolean
    errors?: ValidationError[]
    warnings?: ValidationWarning[]
  }
  ```
- **Auth Required**: Yes (Study member)

## Trial Execution Routes (`trials`)

### `trials.list`
- **Description**: List trials for experiment
- **Type**: Query
- **Input**:
  ```typescript
  {
    experimentId?: string
    studyId?: string
    status?: TrialStatus
    participantId?: string
    wizardId?: string
    page?: number
    limit?: number
  }
  ```
- **Output**: Paginated trial list
- **Auth Required**: Yes (Study member)

### `trials.get`
- **Description**: Get trial details
- **Type**: Query
- **Input**: `{ id: string }`
- **Output**: Trial object with events
- **Auth Required**: Yes (Study member)

### `trials.create`
- **Description**: Schedule new trial
- **Type**: Mutation
- **Input**:
  ```typescript
  {
    experimentId: string
    participantId?: string
    wizardId?: string
    scheduledAt?: Date
    parameters?: Record<string, any>
  }
  ```
- **Output**: Created trial object
- **Auth Required**: Yes (Study researcher)

### `trials.update`
- **Description**: Update trial details
- **Type**: Mutation
- **Input**:
  ```typescript
  {
    id: string
    participantId?: string
    wizardId?: string
    scheduledAt?: Date
    status?: TrialStatus
    notes?: string
  }
  ```
- **Output**: Updated trial object
- **Auth Required**: Yes (Study researcher/wizard)

### `trials.start`
- **Description**: Begin trial execution
- **Type**: Mutation
- **Input**: `{ trialId: string }`
- **Output**:
  ```typescript
  {
    success: boolean
    sessionToken: string
    websocketUrl: string
  }
  ```
- **Auth Required**: Yes (Assigned wizard)

### `trials.complete`
- **Description**: Mark trial as completed
- **Type**: Mutation
- **Input**:
  ```typescript
  {
    trialId: string
    notes?: string
  }
  ```
- **Output**: Updated trial object
- **Auth Required**: Yes (Assigned wizard)

### `trials.abort`
- **Description**: Abort trial execution
- **Type**: Mutation
- **Input**:
  ```typescript
  {
    trialId: string
    reason: string
  }
  ```
- **Output**: Updated trial object
- **Auth Required**: Yes (Assigned wizard)

### `trials.logEvent`
- **Description**: Log trial event
- **Type**: Mutation
- **Input**:
  ```typescript
  {
    trialId: string
    eventType: string
    actionId?: string
    data?: Record<string, any>
  }
  ```
- **Output**: Event object
- **Auth Required**: Yes (Assigned wizard)

### `trials.addIntervention`
- **Description**: Record wizard intervention
- **Type**: Mutation
- **Input**:
  ```typescript
  {
    trialId: string
    interventionType: string
    description?: string
    parameters?: Record<string, any>
    reason?: string
  }
  ```
- **Output**: Intervention object
- **Auth Required**: Yes (Assigned wizard)

### `trials.getEvents`
- **Description**: Get trial event timeline
- **Type**: Query
- **Input**:
  ```typescript
  {
    trialId: string
    eventType?: string
    startTime?: Date
    endTime?: Date
  }
  ```
- **Output**: Array of event objects
- **Auth Required**: Yes (Study member)

## Participant Management Routes (`participants`)

### `participants.list`
- **Description**: List participants in a study
- **Type**: Query
- **Input**:
  ```typescript
  {
    studyId: string
    page?: number
    limit?: number
    search?: string
  }
  ```
- **Output**: Paginated participant list. Each participant object in this response includes a computed `trialCount` field (number of linked trials) plus derived consent metadata; sensitive fields like `demographics` and `notes` are omitted in this list view.
- **Auth Required**: Yes (Study member)

### `participants.get`
- **Description**: Get participant details
- **Type**: Query
- **Input**: `{ id: string }`
- **Output**: Participant object (sensitive data based on permissions)
- **Auth Required**: Yes (Study member)

### `participants.create`
- **Description**: Register new participant
- **Type**: Mutation
- **Input**:
  ```typescript
  {
    studyId: string
    participantCode: string
    email?: string
    name?: string
    demographics?: Record<string, any>
  }
  ```
- **Output**: Created participant object (does NOT include `notes` or `trialCount`; `trialCount` is computed and only appears in list output as an aggregate)
- **Auth Required**: Yes (Study researcher)

### `participants.update`
- **Description**: Update participant information
- **Type**: Mutation
- **Input**: Participant object with id
- **Output**: Updated participant object
- **Auth Required**: Yes (Study researcher)

### `participants.delete`
- **Description**: Remove participant data
- **Type**: Mutation
- **Input**: `{ id: string }`
- **Output**: `{ success: boolean }`
- **Auth Required**: Yes (Study researcher)

### `participants.recordConsent`
- **Description**: Record participant consent
- **Type**: Mutation
- **Input**:
  ```typescript
  {
    participantId: string
    consentFormId: string
    signatureData?: string
    ipAddress?: string
  }
  ```
- **Output**: Consent record object
- **Auth Required**: Yes (Study researcher/wizard)

## Robot and Plugin Routes (`robots`)

### `robots.list`
- **Description**: List available robots
- **Type**: Query
- **Input**: None
- **Output**: Array of robot objects
- **Auth Required**: Yes

### `robots.get`
- **Description**: Get robot details
- **Type**: Query
- **Input**: `{ id: string }`
- **Output**: Robot object with capabilities
- **Auth Required**: Yes

### `robots.testConnection`
- **Description**: Test robot connectivity
- **Type**: Mutation
- **Input**:
  ```typescript
  {
    robotId: string
    configuration: Record<string, any>
  }
  ```
- **Output**:
  ```typescript
  {
    connected: boolean
    latency?: number
    error?: string
  }
  ```
- **Auth Required**: Yes (Study researcher)

### `plugins.list`
- **Description**: List available plugins
- **Type**: Query
- **Input**:
  ```typescript
  {
    robotId?: string
    trustLevel?: PluginTrustLevel
  }
  ```
- **Output**: Array of plugin objects
- **Auth Required**: Yes

### `plugins.get`
- **Description**: Get plugin details
- **Type**: Query
- **Input**: `{ id: string }`
- **Output**: Plugin object with action definitions
- **Auth Required**: Yes

### `plugins.install`
- **Description**: Install plugin for study
- **Type**: Mutation
- **Input**:
  ```typescript
  {
    studyId: string
    pluginId: string
    configuration?: Record<string, any>
  }
  ```
- **Output**: Installation record
- **Auth Required**: Yes (Study researcher)

### `plugins.uninstall`
- **Description**: Remove plugin from study
- **Type**: Mutation
- **Input**:
  ```typescript
  {
    studyId: string
    pluginId: string
  }
  ```
- **Output**: `{ success: boolean }`
- **Auth Required**: Yes (Study researcher)

### `plugins.getActions`
- **Description**: Get available actions for robot
- **Type**: Query
- **Input**:
  ```typescript
  {
    studyId: string
    robotId: string
  }
  ```
- **Output**: Array of action definitions
- **Auth Required**: Yes (Study member)

## Media and Data Routes (`media`)

### `media.uploadVideo`
- **Description**: Upload video file
- **Type**: Mutation
- **Input**:
  ```typescript
  {
    trialId: string
    file: File
    startTimestamp: Date
    endTimestamp?: Date
  }
  ```
- **Output**: Media capture object
- **Auth Required**: Yes (Study member)

### `media.uploadAudio`
- **Description**: Upload audio file
- **Type**: Mutation
- **Input**: Similar to uploadVideo
- **Output**: Media capture object
- **Auth Required**: Yes (Study member)

### `media.list`
- **Description**: List media files for trial
- **Type**: Query
- **Input**:
  ```typescript
  {
    trialId: string
    mediaType?: MediaType
  }
  ```
- **Output**: Array of media objects
- **Auth Required**: Yes (Study member)

### `media.getUrl`
- **Description**: Get presigned URL for media
- **Type**: Query
- **Input**: `{ mediaId: string }`
- **Output**:
  ```typescript
  {
    url: string
    expiresAt: Date
  }
  ```
- **Auth Required**: Yes (Study member)

### `media.delete`
- **Description**: Delete media file
- **Type**: Mutation
- **Input**: `{ mediaId: string }`
- **Output**: `{ success: boolean }`
- **Auth Required**: Yes (Study researcher)

### `sensorData.record`
- **Description**: Record sensor data batch
- **Type**: Mutation
- **Input**:
  ```typescript
  {
    trialId: string
    sensorType: string
    data: Array<{
      timestamp: Date
      values: Record<string, any>
      robotState?: Record<string, any>
    }>
  }
  ```
- **Output**: `{ recordedCount: number }`
- **Auth Required**: Yes (System/Robot)

### `sensorData.query`
- **Description**: Query sensor data
- **Type**: Query
- **Input**:
  ```typescript
  {
    trialId: string
    sensorType?: string
    startTime: Date
    endTime: Date
    limit?: number
  }
  ```
- **Output**: Array of sensor readings
- **Auth Required**: Yes (Study member)

## Analysis Routes (`analysis`)

### `analysis.createAnnotation`
- **Description**: Add annotation to trial
- **Type**: Mutation
- **Input**:
  ```typescript
  {
    trialId: string
    timestampStart: Date
    timestampEnd?: Date
    category?: string
    description: string
    tags?: string[]
  }
  ```
- **Output**: Annotation object
- **Auth Required**: Yes (Study member)

### `analysis.updateAnnotation`
- **Description**: Update existing annotation
- **Type**: Mutation
- **Input**: Annotation object with id
- **Output**: Updated annotation
- **Auth Required**: Yes (Annotation creator)

### `analysis.deleteAnnotation`
- **Description**: Remove annotation
- **Type**: Mutation
- **Input**: `{ id: string }`
- **Output**: `{ success: boolean }`
- **Auth Required**: Yes (Annotation creator)

### `analysis.getAnnotations`
- **Description**: Get annotations for trial
- **Type**: Query
- **Input**:
  ```typescript
  {
    trialId: string
    category?: string
    annotatorId?: string
  }
  ```
- **Output**: Array of annotations
- **Auth Required**: Yes (Study member)

### `analysis.exportData`
- **Description**: Export study data
- **Type**: Mutation
- **Input**:
  ```typescript
  {
    studyId: string
    exportType: ExportType
    format: ExportFormat
    filters?: {
      experiments?: string[]
      trials?: string[]
      dateRange?: {
        start: Date
        end: Date
      }
      includeMedia?: boolean
    }
  }
  ```
- **Output**: Export job object
- **Auth Required**: Yes (Study researcher)

### `analysis.getExportStatus`
- **Description**: Check export job status
- **Type**: Query
- **Input**: `{ jobId: string }`
- **Output**:
  ```typescript
  {
    status: JobStatus
    progress?: number
    downloadUrl?: string
    error?: string
  }
  ```
- **Auth Required**: Yes (Job creator)

## Collaboration Routes (`collaboration`)

### `collaboration.createComment`
- **Description**: Add comment to resource
- **Type**: Mutation
- **Input**:
  ```typescript
  {
    resourceType: "study" | "experiment" | "trial"
    resourceId: string
    content: string
    parentId?: string
    metadata?: any
  }
  ```
- **Output**: Comment object
- **Auth Required**: Yes (Study member)

### `collaboration.getComments`
- **Description**: Get comments for resource
- **Type**: Query
- **Input**:
  ```typescript
  {
    resourceType: "study" | "experiment" | "trial"
    resourceId: string
    parentId?: string
    includeReplies?: boolean
    limit?: number
    offset?: number
  }
  ```
- **Output**: Array of comments
- **Auth Required**: Yes (Study member)

### `collaboration.deleteComment`
- **Description**: Delete comment (soft)
- **Type**: Mutation
- **Input**: `{ id: string }`
- **Output**: `{ success: boolean }`
- **Auth Required**: Yes (Comment author)

### `collaboration.uploadAttachment`
- **Description**: Upload file attachment
- **Type**: Mutation
- **Input**:
  ```typescript
  {
    resourceType: "study" | "experiment" | "trial"
    resourceId: string
    fileName: string
    fileSize: number
    contentType: string
    description?: string
  }
  ```
- **Output**: 
  ```typescript
  {
    attachment: AttachmentObject
    uploadUrl: string
  }
  ```
- **Auth Required**: Yes (Study member)

### `collaboration.createShareLink`
- **Description**: Create token-based shareable link for a resource
- **Type**: Mutation
- **Input**:
  ```typescript
  {
    resourceType: "study" | "experiment" | "trial"
    resourceId: string
    permissions?: ("read" | "comment" | "annotate")[]
    expiresAt?: Date
    description?: string
  }
  ```
- **Output**:
  ```typescript
  {
    id: string
    studyId: string
    resourceType: string
    resourceId: string
    shareToken: string
    shareUrl: string
    permissions: string[]
    expiresAt?: Date
    createdAt: Date
  }
  ```
- **Auth Required**: Yes (Study owner/researcher)

### `collaboration.getSharedResources`
- **Description**: Get resources shared by the current user
- **Type**: Query
- **Input**:
  ```typescript
  {
    limit?: number
    offset?: number
  }
  ```
- **Output**: Array of shared resources with share URLs
- **Auth Required**: Yes

### `collaboration.revokeShare`
- **Description**: Revoke a share link
- **Type**: Mutation
- **Input**: `{ shareId: string }`
- **Output**: `{ success: boolean }`
- **Auth Required**: Yes (Share creator)

### `collaboration.accessSharedResource`
- **Description**: Access a shared resource via token (public endpoint)
- **Type**: Query
- **Input**: `{ shareToken: string }`
- **Output**:
  ```typescript
  {
    resourceType: string
    resourceId: string
    permissions: string[]
  }
  ```
- **Auth Required**: No (Public endpoint)

## System Administration Routes (`admin`)

### `admin.getSystemStats`
- **Description**: Get system statistics
- **Type**: Query
- **Input**: None
- **Output**:
  ```typescript
  {
    userCount: number
    studyCount: number
    trialCount: number
    storageUsed: number
    activeUsers: number
  }
  ```
- **Auth Required**: Yes (Administrator)

### `admin.getSystemSettings`
- **Description**: Get system configuration
- **Type**: Query
- **Input**: None
- **Output**: Settings object
- **Auth Required**: Yes (Administrator)

### `admin.updateSystemSettings`
- **Description**: Update system configuration
- **Type**: Mutation
- **Input**:
  ```typescript
  {
    key: string
    value: any
  }
  ```
- **Output**: Updated settings
- **Auth Required**: Yes (Administrator)

### `admin.getAuditLog`
- **Description**: Query audit log
- **Type**: Query
- **Input**:
  ```typescript
  {
    userId?: string
    action?: string
    resourceType?: string
    startDate?: Date
    endDate?: Date
    page?: number
    limit?: number
  }
  ```
- **Output**: Paginated audit entries
- **Auth Required**: Yes (Administrator)

### `admin.createBackup`
- **Description**: Initiate system backup
- **Type**: Mutation
- **Input**:
  ```typescript
  {
    includeMedia?: boolean
    encryptionKey?: string
  }
  ```
- **Output**: Backup job object
- **Auth Required**: Yes (Administrator)

## WebSocket Events

### Trial Execution Events
- `trial.started`: Trial execution began
- `trial.action.started`: Action execution started
- `trial.action.completed`: Action execution completed
- `trial.intervention`: Wizard intervention occurred
- `trial.error`: Error during execution
- `trial.completed`: Trial finished
- `trial.aborted`: Trial was aborted

### Collaboration Events
- `study.member.joined`: New member added
- `study.member.left`: Member removed
- `comment.created`: New comment added
- `annotation.created`: New annotation added

### System Events
- `plugin.status`: Plugin connection status change
- `export.progress`: Export job progress update
- `system.maintenance`: System maintenance notification

## Error Handling

All routes return consistent error responses:

```typescript
{
  error: {
    code: string // e.g., 'UNAUTHORIZED', 'NOT_FOUND', 'VALIDATION_ERROR'
    message: string
    details?: any
  }
}
```

Common error codes:
- `UNAUTHORIZED`: User not authenticated
- `FORBIDDEN`: User lacks permission
- `NOT_FOUND`: Resource doesn't exist
- `VALIDATION_ERROR`: Input validation failed
- `CONFLICT`: Resource conflict (e.g., duplicate)
- `INTERNAL_ERROR`: Server error

## Rate Limiting

- Authentication endpoints: 5 requests per minute
- File uploads: 10 per hour per user
- Data exports: 5 per hour per study
- General API calls: 100 per minute per user