# What Is the Purpose of the Models Directory in Karakeep?

> Discover the purpose of the models directory in Karakeep. This crucial layer handles database access, business logic, and security for core entities like users, bookmarks, and tags.

- Repository: [Karakeep App/karakeep](https://github.com/karakeep-app/karakeep)
- Tags: internals
- Published: 2026-07-07

---

**The models directory in Karakeep serves as the domain-model layer that encapsulates database access, business logic, and security rules for core entities like users, bookmarks, and tags.**

The `karakeep-app/karakeep` repository organizes its backend logic within the `packages/trpc/models` folder, which functions as the central data-access layer for the application. This directory isolates all database interactions and domain logic from the tRPC routing layer, ensuring that **security checks**, **validation rules**, and **transactional safety** remain consistent across the API surface.

## Architectural Role and Design Philosophy

The models directory implements a **domain-model pattern** where each file defines a class representing a core system entity. Unlike simple data transfer objects, these classes bundle data access methods with business logic, acting as the sole authority for how the application interacts with the database schema defined in `@karakeep/db/schema`.

Each model class shares a standardized constructor signature:

```typescript
constructor(protected ctx: AuthedContext, public <entity>: typeof <table>.$inferSelect)

```

The `ctx` parameter carries the authenticated user session and a Drizzle ORM database instance, enabling every method to enforce **per-user security boundaries** automatically. This design keeps the tRPC routers thin, delegating complex operations to these domain models while maintaining strict authorization checks.

## Core Domain Models and Responsibilities

The `packages/trpc/models` directory contains specialized classes for every major entity in the system:

- **`User`** ([`users.ts`](https://github.com/karakeep-app/karakeep/blob/main/users.ts)): Handles authentication flows including sign-up, password reset, email verification, and settings updates. It encapsulates user-specific permission checks and statistics aggregation while managing the `TRPCError({ code: "FORBIDDEN" })` pattern for unauthorized access attempts.

- **`Bookmark`** ([`bookmarks.ts`](https://github.com/karakeep-app/karakeep/blob/main/bookmarks.ts)): Provides the primary interface for creating, retrieving, and modifying bookmarks. It manages content assembly, ownership validation, and integrates with the `Webhooks.service` to notify external systems of changes.

- **`Tag`** ([`tags.ts`](https://github.com/karakeep-app/karakeep/blob/main/tags.ts)): Manages tag creation, filtering, and pagination while enforcing per-user isolation. It provides usage statistics and cleanup utilities for orphaned tags via methods like `deleteUnused`.

- **`Asset`** ([`assets.ts`](https://github.com/karakeep-app/karakeep/blob/main/assets.ts)): Supplies lifecycle management for file attachments, including listing, attachment/detachment logic via `attachAsset`, type translation, and cleanup of orphaned files.

- **`List`** ([`lists.ts`](https://github.com/karakeep-app/karakeep/blob/main/lists.ts)): Manages user-defined collections of bookmarks, handling creation, retrieval, and sharing logic.

- **`Rules`** ([`rules.ts`](https://github.com/karakeep-app/karakeep/blob/main/rules.ts)): Stores user-specific automation rules such as auto-tagging and summarization triggers.

Specialized service modules handle cross-cutting concerns:

- **`Webhooks.service`** ([`webhooks.service.ts`](https://github.com/karakeep-app/karakeep/blob/main/webhooks.service.ts)): Delivers webhook callbacks when bookmarks change.
- **`Webhooks.repo`** ([`webhooks.repo.ts`](https://github.com/karakeep-app/karakeep/blob/main/webhooks.repo.ts)): Persists webhook subscription records.
- **`ImportSessions`** ([`importSessions.service.ts`](https://github.com/karakeep-app/karakeep/blob/main/importSessions.service.ts)): Manages bulk import workflows for RSS feeds and other sources.
- **`Highlights`** ([`highlights.ts`](https://github.com/karakeep-app/karakeep/blob/main/highlights.ts)): Manages text annotations on bookmark assets.
- **`Feeds`** ([`feeds.ts`](https://github.com/karakeep-app/karakeep/blob/main/feeds.ts)): Controls RSS feed integration and polling schedules.
- **`Backups`** ([`backups.ts`](https://github.com/karakeep-app/karakeep/blob/main/backups.ts)): Handles backup scheduling and retrieval operations.

## Security Patterns and Side-Effects

Every model method receives an `AuthedContext` object containing the current user identity and database connection. This pattern ensures that queries automatically filter by `userId`, preventing data leakage between accounts. The models also handle side-effects transactionally, such as re-indexing search data after bookmark updates or sending verification emails during user creation.

## Practical Usage Examples

The tRPC routers consume these models to expose the public API. Below are typical interaction patterns from the Karakeep source code:

### Creating a New User

```typescript
// Used in the signup tRPC procedure
await User.create(ctx, {
  name: "Alice",
  email: "alice@example.com",
  password: "s3cr3t",
});

```

### Retrieving a Bookmark with Ownership Validation

```typescript
// Ensures the caller can view the specific bookmark
const bm = await Bookmark.bareFromId(ctx, "bookmark-123");

```

### Attaching Assets to Bookmarks

```typescript
await Asset.attachAsset(ctx, {
  bookmarkId: "bookmark-123",
  asset: { id: "asset-456", assetType: "AVATAR" },
});

```

### Querying Tags with Pagination

```typescript
const { tags, nextCursor } = await Tag.getAll(ctx, {
  nameContains: "project",
  sortBy: "usage",
  pagination: { page: 0, limit: 20 },
});

```

### Administrative Cleanup Operations

```typescript
// Admin-only helper to remove unused tags
const removedCount = await Tag.deleteUnused(ctx);

```

Each call internally uses the Drizzle ORM to fetch or modify rows, respecting the current user's permissions while triggering necessary side-effects like search re-indexing or webhook delivery.

## Summary

- The `packages/trpc/models` directory acts as the **domain-model layer** for the Karakeep monorepo, separating data access from routing logic.
- Each file defines a class (e.g., `User`, `Bookmark`, `Tag`) that encapsulates **database queries**, **business rules**, and **security validation**.
- Models accept an `AuthedContext` parameter to enforce **per-user data isolation** automatically across all operations.
- The layer handles **side-effects** such as email delivery, webhook notifications, and search indexing within transactional boundaries.
- Key files include [`users.ts`](https://github.com/karakeep-app/karakeep/blob/main/users.ts), [`bookmarks.ts`](https://github.com/karakeep-app/karakeep/blob/main/bookmarks.ts), [`tags.ts`](https://github.com/karakeep-app/karakeep/blob/main/tags.ts), [`assets.ts`](https://github.com/karakeep-app/karakeep/blob/main/assets.ts), and service modules like [`webhooks.service.ts`](https://github.com/karakeep-app/karakeep/blob/main/webhooks.service.ts) and [`importSessions.service.ts`](https://github.com/karakeep-app/karakeep/blob/main/importSessions.service.ts).

## Frequently Asked Questions

### What is the models directory in Karakeep responsible for?

The models directory in Karakeep is responsible for defining the **domain-model layer** that contains all database access logic, business rules, and security checks. Located at `packages/trpc/models`, each file implements a class representing a core entity (User, Bookmark, Tag, etc.) that the tRPC routers use to serve API requests while enforcing per-user permissions.

### How does the Karakeep models directory enforce security?

Security enforcement happens through the `AuthedContext` pattern passed to every model constructor. This context object contains the authenticated user and database connection, allowing methods to automatically filter queries by `userId` and throw `TRPCError({ code: "FORBIDDEN" })` when callers attempt to access resources they don't own, as seen in the `Tag` and `Bookmark` models.

### What is the relationship between the models directory and tRPC routers in Karakeep?

The tRPC routers in Karakeep act as thin controllers that delegate all business logic to the models directory. While routers handle request/response formatting and validation, they import classes from `packages/trpc/models` to perform actual data operations, ensuring consistent application of business rules across the API surface without duplicating logic.

### Which files are included in the Karakeep models directory?

The models directory includes entity classes like [`users.ts`](https://github.com/karakeep-app/karakeep/blob/main/users.ts), [`bookmarks.ts`](https://github.com/karakeep-app/karakeep/blob/main/bookmarks.ts), [`tags.ts`](https://github.com/karakeep-app/karakeep/blob/main/tags.ts), [`assets.ts`](https://github.com/karakeep-app/karakeep/blob/main/assets.ts), and [`lists.ts`](https://github.com/karakeep-app/karakeep/blob/main/lists.ts), plus service-specific files such as [`webhooks.service.ts`](https://github.com/karakeep-app/karakeep/blob/main/webhooks.service.ts), [`webhooks.repo.ts`](https://github.com/karakeep-app/karakeep/blob/main/webhooks.repo.ts), [`rules.ts`](https://github.com/karakeep-app/karakeep/blob/main/rules.ts), [`importSessions.service.ts`](https://github.com/karakeep-app/karakeep/blob/main/importSessions.service.ts), [`highlights.ts`](https://github.com/karakeep-app/karakeep/blob/main/highlights.ts), [`feeds.ts`](https://github.com/karakeep-app/karakeep/blob/main/feeds.ts), and [`backups.ts`](https://github.com/karakeep-app/karakeep/blob/main/backups.ts). Each file focuses on a specific domain area while sharing the common constructor pattern with `AuthedContext` and Drizzle ORM integration.