# Dependency Management

## Overview

The Oshun monorepo uses pnpm 10+ with the `catalog:` feature for centralized
version management. This ensures consistent dependency versions across all
projects and simplifies upgrades.

---

## pnpm Catalog

### What is the Catalog?

The catalog is defined in `pnpm-workspace.yaml` and provides a single source of
truth for dependency versions. Instead of specifying versions in each
`package.json`, projects reference the catalog:

```json
// package.json
{
  "dependencies": {
    "hono": "catalog:",
    "zod": "catalog:",
    "ioredis": "catalog:"
  }
}
```

The actual versions are resolved from the `catalog:` section of
`pnpm-workspace.yaml`:

```yaml
catalog:
  hono: ^4.0.0
  zod: ^3.23.0
  ioredis: ^5.3.2
```

### Benefits

1. **Single version per dependency** - No version conflicts across projects
2. **Easy upgrades** - Change the version once in the catalog
3. **Lockfile consistency** - pnpm-lock.yaml stays clean
4. **IDE support** - pnpm resolves catalog references transparently

### Common Catalog Entries

Below are key dependencies managed through the catalog. See
`pnpm-workspace.yaml` for the complete list.

**Frameworks:**

| Package   | Version  | Purpose              |
| --------- | -------- | -------------------- |
| `hono`    | ^4.0.0   | HTTP framework       |
| `fastify` | ^4.28.1  | Alternative HTTP     |
| `next`    | ^14.2.21 | React meta-framework |
| `react`   | ^18.3.1  | UI library           |

**Database:**

| Package          | Version | Purpose           |
| ---------------- | ------- | ----------------- |
| `pg`             | ^8.11.3 | PostgreSQL client |
| `@prisma/client` | ^5.20.0 | Prisma ORM        |
| `prisma`         | ^5.20.0 | Prisma CLI        |
| `ioredis`        | ^5.3.2  | Redis client      |
| `drizzle-orm`    | ^0.38.4 | Drizzle ORM       |
| `knex`           | ^3.1.0  | Query builder     |

**AI/ML:**

| Package                 | Version | Purpose       |
| ----------------------- | ------- | ------------- |
| `openai`                | ^4.0.0  | OpenAI SDK    |
| `@anthropic-ai/sdk`     | ^0.30.0 | Anthropic SDK |
| `@google/generative-ai` | ^0.21.0 | Google AI SDK |
| `replicate`             | ^0.34.0 | Replicate SDK |

**Validation & Types:**

| Package       | Version | Purpose             |
| ------------- | ------- | ------------------- |
| `zod`         | ^3.23.0 | Schema validation   |
| `typescript`  | ~5.6.3  | TypeScript compiler |
| `@types/node` | ^22.0.0 | Node.js type defs   |

**Testing:**

| Package               | Version | Purpose               |
| --------------------- | ------- | --------------------- |
| `vitest`              | ^1.6.1  | Test framework        |
| `@vitest/coverage-v8` | ^1.6.1  | Coverage provider     |
| `@playwright/test`    | ^1.48.2 | E2E testing           |
| `testcontainers`      | ^10.7.0 | Container-based tests |

**Observability:**

| Package                         | Version | Purpose            |
| ------------------------------- | ------- | ------------------ |
| `prom-client`                   | ^15.1.3 | Prometheus metrics |
| `@opentelemetry/api`            | ^1.9.0  | OpenTelemetry API  |
| `@opentelemetry/sdk-trace-node` | ^1.28.0 | Tracing SDK        |
| `@sentry/node`                  | ^8.0.0  | Error tracking     |
| `pino`                          | ^9.0.0  | Structured logging |

**AWS SDK:**

| Package                      | Version  | Purpose            |
| ---------------------------- | -------- | ------------------ |
| `@aws-sdk/client-s3`         | ^3.600.0 | S3 operations      |
| `@aws-sdk/client-cloudwatch` | ^3.600.0 | CloudWatch metrics |
| `@aws-sdk/lib-storage`       | ^3.600.0 | Multipart uploads  |

---

## Workspace Dependencies

For internal monorepo dependencies, use the `workspace:*` protocol:

```json
{
  "dependencies": {
    "@oshun/database": "workspace:*",
    "@oshun/logger": "workspace:*"
  }
}
```

This always resolves to the local workspace version, ensuring you never
accidentally pull a published version.

---

## Adding a New Dependency

### To a single project

```bash
pnpm add <package> --filter <project-name>
```

### To the catalog

1. Add the version to `pnpm-workspace.yaml`:

   ```yaml
   catalog:
     new-package: ^1.0.0
   ```

2. Reference it in your `package.json`:

   ```json
   {
     "dependencies": {
       "new-package": "catalog:"
     }
   }
   ```

3. Run `pnpm install` to update the lockfile.

### To shared (root devDependencies)

For tools used across the monorepo (e.g., `typescript`, `eslint`):

```bash
pnpm add -D -w <package>
```

---

## Upgrading Dependencies

### Upgrade a catalog entry

1. Update the version in `pnpm-workspace.yaml`
2. Run `pnpm install`
3. Run `pnpm nx affected --target=build` to verify
4. Run `pnpm nx affected --target=test` to verify

### Audit for vulnerabilities

```bash
pnpm audit
```

---

## Path Aliases

TypeScript path aliases are defined in `tsconfig.base.json` at the monorepo
root. These map `@oshun/*` and `@{domain}/*` imports to source directories:

```json
{
  "compilerOptions": {
    "paths": {
      "@oshun/database": ["libs/shared/database/src/index.ts"],
      "@oshun/logger": ["libs/shared/logger/src/index.ts"],
      "@iris/conversation-core": ["libs/iris/conversation-core/src/index.ts"]
    }
  }
}
```

These same aliases are replicated in the Vitest base configuration for test
resolution. See [Testing Strategy](./testing.md) for details.

---

## Workspace Configuration

The `pnpm-workspace.yaml` `packages` section defines which directories are pnpm
workspace packages:

```yaml
packages:
  - apps/{domain}/* # All apps per domain
  - libs/shared/* # Shared foundation
  - libs/{domain}/* # Domain-specific libs
  - libs/contracts # Cross-domain contracts
  - libs/proto # Protocol Buffers
  - libs/openapi # OpenAPI specs
  - tools/* # Build tools
```

---

## Further Reading

- [Getting Started](./getting-started.md) - Initial setup with `pnpm install`
- [Adding a New Library](./adding-new-library.md) - Creating new packages
- [Architecture](./architecture.md) - Monorepo structure
