# @izri/trpc

> Type-safe API layer using tRPC for the Izri platform

## Overview

The tRPC package provides a complete type-safe API layer that connects the frontend and backend. It uses tRPC for end-to-end typing, Zod for validation, and Drizzle for database operations. Authentication integrates Better Auth via the Hono adapter.

## Package Structure

```
packages/trpc/
├── src/
│   ├── index.ts          # Main package exports
│   ├── trpc.ts           # tRPC instance and procedures
│   ├── context.ts        # Context creation (Hono + Better Auth)
│   └── routers/
│       ├── index.ts      # Root router (AppRouter)
│       ├── auth.ts       # Authentication & session management
│       ├── projects.ts   # Project management
│       ├── organizations.ts  # Organization operations
│       └── analysis.ts   # Repository analysis
└── package.json
```

## Context

Context exposes database and auth/session data and raw headers:

```ts
interface Context {
  db: DrizzleDB
  user: AuthenticatedUser | null
  session: Session | null
  isAuthenticated: boolean
  headers: Headers
}
```

Created in `src/context.ts` using Better Auth:

```ts
const sessionData = await auth.api.getSession({ headers })
// user, session, isAuthenticated derived from sessionData
```

Note: Permissions are organization-scoped; there are no global user roles.

## Base procedures

```ts
export const publicProcedure = t.procedure
export const protectedProcedure = t.procedure.use(/* checks ctx.isAuthenticated */)
export const router = t.router
```

## Routers and procedures (highlights)

- Root: auth, organizations, projects, analysis, and a public health query

### Auth

- getSession (public): returns { isAuthenticated, session, user }
- listSessions (protected)
- invalidateSession (protected)
- revokeSession (protected)
- revokeOtherSessions (protected)
- getProfile (protected)
- updateProfile (protected)
- getAuditLogs (protected)
- initializeNewUser (public): post-signup helper that creates a default organization for the new user

API tokens: functionality is temporarily removed during Better Auth migration; see docs/features/api-keys.md

### Organizations

- create (protected): create org; creator becomes OWNER
- update (protected): update basic fields; requires OWNER/ADMIN membership
- list (protected): list orgs with the caller’s role
- getBySlug (protected): fetch details by slug
- delete (protected): delete org (owner only)
- createDefaultOrganization helper is exported from this router and used by auth.initializeNewUser

Internals: slugs validated (lowercase letters, numbers, hyphens). IDs generated with `ulid()` from the `ulid` package.

### Projects

- getProjects (public): list caller’s projects; optional organizationId filter; includes latest test run per project
- getProject (protected): fetch by id; returns settings and all runs
- createProject (protected): checks for repository duplication per user; creates default project_settings automatically
- updateProject (protected)
- deleteProject (protected)
- getProjectAnalyses (protected)
- getLatestProjectAnalysis (protected)

IDs for projects and project_settings created with `ulid()` from the `ulid` package.

### Analysis

- analyzeRepository (protected): verifies project ownership, runs repository analysis, and stores results in project_analyses using an upsert on (projectId, commitSha)

Current analyzer used: RepositoryAnalyzer (legacy). EnhancedRepositoryAnalyzer is available in @izri/repo-analyzer but not yet wired here. See repo-analyzer docs for migration guidance.

## Examples

```ts
// Client example
const { project } = await trpc.projects.createProject.mutate({
  name: 'My Project',
  repository: 'https://github.com/user/repo',
  branch: 'main',
  language: 'typescript',
  framework: 'nextjs',
  organizationId: 'org_123',
  userEmail: 'user@example.com',
})
```

```ts
// Health check
await trpc.health.query() // { ok: true }
```

## Notes

- Use env via @izri/shared in any server using this router.
- **ID strategy:** All tables (auth and application) use ULID generated via `ulid()` from the `ulid` package; all stored as varchar(191).
- Org-scoped permission model applies to all protected procedures.