---
title: Isolate Database Access Behind Repositories
impact: CRITICAL
impactDescription: Enables technology changes without codebase-wide refactors
tags: data, repository, prisma, nestjs, isolation
---
## Паспорт документа

- Статус документа: living standard
- Актуально на: 28 марта 2026 года
- Владелец: backend/platform-команда
- Пересмотр: при изменении инженерной практики, CI/CD, архитектурных правил или локального workflow
- Область применения: внутренние rule/reference-card документы для инженерной команды
- Связанные документы:
  - [Индекс Agents](../README.md)
  - [Команды разработки](../commands.md)
  - [Инженерные принципы](../../governance/engineering-principles.md)

## Isolate Database Access Behind Repositories

**Impact: CRITICAL**

All database access goes through Repository classes. Repositories are the only code that knows about Prisma. Services depend on repositories via NestJS Dependency Injection.

**Incorrect (Prisma leaking into service):**

```typescript
@Injectable()
export class ItemService {
  constructor(private prisma: PrismaService) {}

  async findBySlug(slug: string) {
    return this.prisma.item.findFirst({
      where: { slug },
      include: { seller: true }
    });
  }
}
```

**Correct (Repository abstraction):**

```typescript
// repositories/item.repository.ts
@Injectable()
export class ItemRepository {
  constructor(private readonly prisma: PrismaService) {}

  async findBySlug(slug: string): Promise<ItemDetailDTO | null> {
    const item = await this.prisma.$replica().item.findFirst({
      where: { slug, status: 'PUBLISHED' },
      select: {
        id: true,
        title: true,
        slug: true,
        price: true,
        seller: {
          select: { id: true, name: true, logoUrl: true }
        }
      }
    });
    return item;
  }
}

// item.service.ts — no Prisma knowledge
@Injectable()
export class ItemService {
  constructor(private readonly itemRepo: ItemRepository) {}

  async findBySlug(slug: string): Promise<ItemDetailDTO | null> {
    return this.itemRepo.findBySlug(slug);
  }
}
```

**Rules:**
- All Prisma calls live in `*Repository` classes
- Repositories return DTOs or plain objects, never raw Prisma types
- No business logic in repositories — only data access
- Services depend on repositories, never on PrismaService directly
- Repositories use `$replica()` for read operations, default client for writes
