# @timeback/types

TypeScript types and Zod schemas for the Timeback platform (private, monorepo-only).

## Quick Start

```typescript
import { OneRosterUserCreateInput } from '@timeback/types/zod'

import type { User } from '@timeback/types/protocols/oneroster'
```

## Where do I import what?

| I need…                                  | Import from…                           |
| ---------------------------------------- | -------------------------------------- |
| **Runtime validation schemas**           | `@timeback/types/zod`                  |
| **Request/input types (schema-first)**   | `@timeback/types/zod`                  |
| **Domain/response types**                | `@timeback/types/protocols/<protocol>` |
| **SDK types (preferred when available)** | `@timeback/<client>/types`             |

## Directory structure

```
src/
├── index.ts              # Main entrypoint: shared TS types
├── primitives.ts         # Shared primitives (TimebackGrade, TimebackSubject, etc.)
├── config.ts             # Config types
│
├── zod/
│   ├── index.ts          # Main Zod entrypoint
│   ├── primitives.ts     # Shared Zod schemas (clearly sectioned by scope)
│   ├── config.ts         # Config schemas
│   ├── oneroster.ts      # OneRoster input schemas
│   ├── qti.ts            # QTI input schemas
│   ├── caliper.ts        # Caliper input schemas
│   ├── edubridge.ts      # Edubridge input schemas
│   ├── case.ts           # CASE input schemas
│   ├── clr.ts            # CLR input schemas
│   ├── masterytrack.ts   # MasteryTrack input schemas
│   ├── powerpath.ts      # PowerPath input schemas
│   └── webhooks.ts       # Webhooks input schemas
│
└── protocols/
    ├── oneroster/
    │   ├── primitives.ts # OneRoster-specific enums (ScoreStatus, OrganizationType, etc.)
    │   ├── base.ts       # Common types (Base, Ref, CreateResponse)
    │   ├── rostering.ts  # User, Class, Course, Enrollment types
    │   ├── gradebook.ts  # LineItem, Result, Category types
    │   └── ...
    ├── qti/
    │   ├── primitives.ts # QTI-specific enums (LessonType)
    │   ├── base.ts       # Common QTI types
    │   └── ...
    ├── caliper/
    │   └── ...
    ├── edubridge/
    │   └── ...
    ├── case/
    │   └── ...
    ├── clr/
    │   └── ...
    ├── masterytrack/
    │   └── ...
    ├── powerpath/
    │   └── ...
    └── webhooks.ts       # Webhooks types
```

## Tenets

- **Schemas are the source of truth for inputs**: if we validate it, the Zod schema lives in `@timeback/types/zod` and the TS type is inferred from it.
- **Protocols are for domain/response**: protocol folders model entities and response shapes; avoid duplicating request types there.
- **Use public entrypoints only**: don't deep-import internal paths (e.g. `@timeback/types/src/*`).
- **Protocol-specific primitives live in their protocol**: `ScoreStatus` is in `protocols/oneroster/primitives.ts`, not the shared `primitives.ts`.
- **Zod conventions**: `zod/v4`, use `z.loose()` (not `z.passthrough()`), use `z.email()`/`z.url()`.

## Examples

### Validate an input payload (schema-first)

```typescript
import { validateWithSchema } from '@timeback/internal-client-infra'
import { OneRosterUserCreateInput } from '@timeback/types/zod'

import type { UserCreateInput } from '@timeback/types/zod'

function createUser(body: unknown) {
	validateWithSchema(OneRosterUserCreateInput, body, 'create user')
	const input: UserCreateInput = OneRosterUserCreateInput.parse(body)
	return input
}
```

### Use response/domain types

```typescript
import type { StoredEvent } from '@timeback/types/protocols/caliper'
import type { Enrollment, User } from '@timeback/types/protocols/oneroster'
import type { AssessmentTest } from '@timeback/types/protocols/qti'
```
