Migrate from Prisma to Drizzle ORM

Co-Authored-By: Oz <oz-agent@warp.dev>
This commit is contained in:
2026-04-05 01:18:08 +05:00
parent 912946bb00
commit b6f5138390
18 changed files with 1699 additions and 1100 deletions

View File

@@ -4,7 +4,7 @@ Guidelines for AI coding agents working on this repository.
## Project Overview
TypeScript-based scraper for Russian supermarkets (Magnit). Uses Playwright for sessions, Axios for API, PostgreSQL with Prisma ORM.
TypeScript-based scraper for Russian supermarkets (Magnit). Uses Playwright for sessions, Axios for API, PostgreSQL with Drizzle ORM.
## Build & Run Commands
@@ -20,12 +20,13 @@ pnpm enrich # Run product enrichment
pnpm test-db # Test database connection
```
### Prisma Commands
### Drizzle Commands
```bash
pnpm prisma:generate # Generate client after schema changes
pnpm prisma:migrate # Create and apply migrations
pnpm prisma:studio # Open database GUI
pnpm db:generate # Generate migration files
pnpm db:migrate # Apply migrations
pnpm db:push # Push schema changes directly (dev only)
pnpm db:studio # Open database GUI
```
### Running Scripts Directly
@@ -45,13 +46,15 @@ No test framework configured. Manual testing via `pnpm test-db`, `pnpm dev`, Pri
1. External packages first, then internal modules
2. **Always include `.js` extension** for local imports (ESM)
3. Use named imports from Prisma client
3. Use named imports from Drizzle schema
```typescript
import { chromium, Browser } from 'playwright';
import axios from 'axios';
import { Logger } from '../../../utils/logger.js';
import { PrismaClient } from '../../../../generated/prisma/client.js';
import { db } from '../../../config/database.js';
import { products, stores, categories } from '../../../db/schema.js';
import { eq, and, asc } from 'drizzle-orm';
```
### Naming Conventions
@@ -113,15 +116,19 @@ Logger.debug('Debug'); // Only when DEBUG=true
### Services Pattern
- Services receive `PrismaClient` via constructor (DI)
- Services receive `db` (Drizzle instance) via constructor (DI)
- Use `getOrCreate` for idempotent operations
- Never call Prisma directly from scrapers
- Never call Drizzle directly from scrapers
### Database Patterns
- Upsert via composite unique `(externalId, storeId)`
- Upsert via composite unique constraint on `(externalId, storeId)`
- Batch processing: 50 items per batch
- Prices: Float (rubles), converted from kopecks
- Prices: Decimal (rubles), stored as decimal type
- Use `.select().from().where()` for queries
- Use `.insert().values()` for inserts
- Use `.update().set().where()` for updates
- Use `.delete().where()` for deletes
### Comments