Qadam Roadmap
проектdocs/Agents/rules/data-repository-pattern.md

data-repository-pattern.md

Обновлён 1 апр. 2026 г., 12:41 · 0 комментариев


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 документы для инженерной команды
  • Связанные документы:

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):

@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):

// 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