Files
nick-doc/PRD - Mongo Retirement (Full Nuke).md

309 lines
11 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# PRD — Mongo Retirement: Full Code Nuke
**Status:** In Progress
**Date:** 2026-06-06
**Scope:** Remove every Mongoose/MongoDB reference from the codebase and replace Mongo-style ObjectId fields with plain UUID strings throughout.
---
## Context
The Mongo→Postgres migration scaffolding is complete:
- 25 Drizzle schemas cover all 23 collections
- 11 Drizzle repos, 11 Mongo repos, 9 DualWrite fan-out repos
- Backfill scripts written (not yet run against production)
- Factory defaults to `mongo`; reads not yet cut over
- Chat uses a JSONB shim (acceptable for now — normalize later)
This PRD covers the **code-level retirement**: delete all Mongoose artifacts, flip the factory to Postgres-only, remove MongoDB from docker-compose and package.json, and replace `Types.ObjectId` with `string` (UUID) across every interface and schema.
Production data migration (backfill execution + read-cutover per domain) is a **separate, human-gated operation** and is NOT in scope here.
---
## Goals
1. Zero `mongoose` or `mongodb` imports anywhere in `backend/`
2. Zero `Schema.Types.ObjectId` / `Types.ObjectId` field types
3. Zero `_id: ObjectId` interface declarations (replaced with `id: string`)
4. Zero `ObjectId(...)` constructors or `.toString()` coercions on IDs
5. MongoDB service removed from all docker-compose files
6. `mongoose` removed from `package.json`
7. `MONGODB_URI` / `MONGO_*` env vars removed from config and docs
8. Factory defaults to `pg`; Mongo and DualWrite modes deleted
9. Seeds and scripts updated to target Postgres only
10. Frontend: legacy ObjectId validation path removed
---
## Out of Scope
- Backfill execution against production data
- Production env var changes (`REPO_*`, `MONGO_CONNECT_MODE`)
- Chat normalization (JSONB → child tables) — tracked separately
- Drizzle schema changes (schemas are already correct)
- Any Drizzle repo logic changes
---
## Phased Work Plan
### Phase 1 — Factory Cutover & Repo Deletion (Day 1)
**1.1 Factory: delete Mongo + DualWrite modes**
- File: `src/db/repositories/factory.ts`
- Change: remove all `mongo` and `dual` branches; every domain returns its Drizzle repo directly
- Remove `REPO_*` env flag checks (no longer needed)
- Remove all imports of Mongo repos and DualWrite repos
**1.2 Delete Mongo repo files (11 files)**
```
src/db/repositories/mongo/MongoUserRepo.ts
src/db/repositories/mongo/MongoPaymentRepo.ts
src/db/repositories/mongo/MongoPointsRepo.ts
src/db/repositories/mongo/MongoMarketplaceRepo.ts
src/db/repositories/mongo/MongoBlogRepo.ts
src/db/repositories/mongo/MongoNotificationRepo.ts
src/db/repositories/mongo/MongoDisputeRepo.ts
src/db/repositories/mongo/MongoTrezorAccountRepo.ts
src/db/repositories/mongo/MongoDerivedDestinationRepo.ts
src/db/repositories/mongo/MongoChatRepo.ts
src/db/repositories/mongo/MongoReleaseHoldRepo.ts
src/db/repositories/mongo/index.ts
```
**1.3 Delete DualWrite repo files (9 files)**
```
src/db/repositories/dual/DualWriteUserRepo.ts
src/db/repositories/dual/DualWritePaymentRepo.ts
src/db/repositories/dual/DualWritePointsRepo.ts
src/db/repositories/dual/DualWriteMarketplaceRepo.ts
src/db/repositories/dual/DualWriteBlogRepo.ts
src/db/repositories/dual/DualWriteNotificationRepo.ts
src/db/repositories/dual/DualWriteDisputeRepo.ts
src/db/repositories/dual/DualWriteTrezorAccountRepo.ts
src/db/repositories/dual/DualWriteDerivedDestinationRepo.ts
src/db/repositories/dual/index.ts
```
---
### Phase 2 — Mongoose Model Deletion & Interface Extraction (Day 12)
**2.1 Extract pure TS interfaces from each model file**
For each of the 24 model files in `src/models/`, the plan is:
- Keep the `I<Name>` TypeScript interface (with `id: string` replacing `_id: Types.ObjectId`)
- Delete the `new Schema(...)` definition, virtual fields, pre/post hooks
- Delete the `mongoose.model<I<Name>>(...)` export
- Delete the mongoose import
The interface files move to `src/types/models/` (or inline into the Drizzle schema files as inferred types).
**2.2 Convert all `_id` → `id: string` in interfaces**
Key changes per domain:
- `IUser._id: Types.ObjectId``id: string`
- `ICategory._id``id: string`, `parentId: string | null`
- `IPurchaseRequest._id``id: string`, `buyerId/sellerId: string`
- `ISellerOffer._id``id: string`, `sellerId/purchaseRequestId: string`
- `IPayment._id``id: string`, polymorphic fields → `string`
- `IChat._id``id: string`, `senderId/userId: string`
- `IDispute._id``id: string`, all ref fields → `string`
- All others follow same pattern
**2.3 Delete `src/models/` directory after interfaces extracted**
---
### Phase 3 — Mongoose Connection & Config Removal (Day 2)
**3.1 `src/infrastructure/database/connection.ts`**
- Remove `mongoose.connect()` call and all Mongo connection logic
- Remove `MONGO_CONNECT_MODE` handling
- Keep only the Postgres pool initialization
**3.2 `src/shared/config/index.ts`**
- Remove `mongoUri` field
- Remove `MONGODB_URI` env var read
**3.3 `src/services/auth/authStore.ts`**
- Remove `AUTH_FALLBACK_MONGO`, `AUTH_MIRROR_MONGO`, `MONGO_CONNECT_MODE` branches
- Auth reads only from Postgres
**3.4 `src/services/health/healthCheckService.ts`**
- Remove MongoDB health check
- Remove `MONGO_CONNECT_MODE` reference
**3.5 `src/app.ts`**
- Remove `mongoose.connect()` / `connectMongo()` call on startup
- Remove `p.userId.toString()` ObjectId coercions (already string)
---
### Phase 4 — Seeds & Scripts Cleanup (Day 2)
**4.1 Seeds (`src/seeds/`)**
- Remove `mongoose.connect()` from all 7 seed files
- Seeds already have PG-aware paths; remove Mongo dual-path
- `seedUsers.ts`, `seedLevels.ts`, `seedCategories.ts`, etc.
**4.2 Scripts (`src/scripts/`)**
- Remove Mongoose imports from 13 scripts
- Scripts that only operated on Mongo (e.g. `clearChats.ts`, `updateRequestStatus.ts`) — convert to Postgres queries or delete if obsolete
---
### Phase 5 — Backfill Infrastructure (Day 3)
**5.1 Archive backfill scripts** (don't delete — needed for production data migration)
- Move `src/db/backfill/``src/db/backfill/_archive/`
- OR keep as-is but add a `.nocompile` flag / remove from tsconfig paths
- The backfill scripts import mongoose (to read from Mongo) — they're tools for ops, not app code
**5.2 Remove verification layer Mongo references**
- `src/db/verify/shadowRead.ts` — remove Mongo comparison path
- `src/db/verify/rowCounts.ts` — remove Mongo row count queries
- `src/db/verify/checksums.ts` — remove Mongo checksum queries
- `src/db/verify/reconcile.ts` — keep (handles `pg_dualwrite_gaps` replay, still useful)
**5.3 `_idMap.ts`** — keep as a utility for ops scripts only; remove from app imports
---
### Phase 6 — Docker & Dependencies (Day 3)
**6.1 `docker-compose.dev.yml`**
- Remove `mongodb` service block
- Remove `depends_on: mongodb` from backend service
- Remove all `*_STORE=mongo` env vars (Auth, Config, Address, etc.)
- Remove `mongodb_data` volume
**6.2 `docker-compose.production.yml`**
- Same: remove mongodb service, depends_on, volume
**6.3 `deployment/docker-compose.yml`**
- Same: remove mongodb service block
**6.4 `backend/package.json`**
- Remove `mongoose` from dependencies
- Remove `mongodb-memory-server` from devDependencies
**6.5 `.env.example` / `.env.development` / `.env.local`**
- Remove `MONGODB_URI`, `MONGO_CONNECT_MODE`, `AUTH_FALLBACK_MONGO`, `AUTH_MIRROR_MONGO`
- Remove `MONGO_INITDB_*` vars
---
### Phase 7 — Frontend ID Validation Cleanup (Day 3)
**7.1 Remove ObjectId validation branch**
- `frontend/src/sections/request-template/view/seller-shop-view.tsx:78`
- Remove the "legacy 24-hex Mongo ObjectId" validation path
- Keep only UUID validation
**7.2 Audit frontend for other ObjectId references**
- `grep -r 'ObjectId\|[0-9a-f]{24}' frontend/src/`
- Remove any other legacy ID format handling
---
### Phase 8 — TypeScript Compilation Check (Day 3)
- `npm run tsc` — fix all remaining type errors from the migration
- Common issues: `.toString()` on already-string IDs, `_id` vs `id` mismatches, missing UUID imports
---
## Files to Delete (Complete List)
### Mongoose Model Files (24)
```
backend/src/models/User.ts
backend/src/models/Category.ts
backend/src/models/PurchaseRequest.ts
backend/src/models/SellerOffer.ts
backend/src/models/Payment.ts
backend/src/models/Chat.ts
backend/src/models/Dispute.ts
backend/src/models/Review.ts
backend/src/models/Address.ts
backend/src/models/Notification.ts
backend/src/models/TelegramLink.ts
backend/src/models/TelegramSession.ts
backend/src/models/TempVerification.ts
backend/src/models/TrezorAccount.ts
backend/src/models/DerivedDestination.ts
backend/src/models/FundsLedgerEntry.ts
backend/src/models/PointTransaction.ts
backend/src/models/RequestTemplate.ts
backend/src/models/BlogPost.ts
backend/src/models/ConfigSetting.ts
backend/src/models/ConfigSettingHistory.ts
backend/src/models/LevelConfig.ts
backend/src/models/ShopSettings.ts
backend/src/models/index.ts
```
### Mongo Repos (11+index)
```
backend/src/db/repositories/mongo/ (entire directory)
```
### DualWrite Repos (9+index)
```
backend/src/db/repositories/dual/ (entire directory)
```
---
## ID Migration Pattern
Every interface field that was `Types.ObjectId` or `Schema.Types.ObjectId` becomes `string` (UUID).
**Before:**
```typescript
interface ISellerOffer {
_id: Types.ObjectId;
sellerId: Types.ObjectId | string;
purchaseRequestId: Types.ObjectId | string;
}
```
**After:**
```typescript
interface ISellerOffer {
id: string; // UUID
sellerId: string;
purchaseRequestId: string;
}
```
Any code doing `someDoc._id.toString()``someDoc.id` (already a string).
Any code doing `new mongoose.Types.ObjectId(value)` → just use `value` as string.
---
## Risk Register
| Risk | Mitigation |
|---|---|
| App breaks because Mongo isn't seeded in dev | Run `npm run seed:pg` before removing Mongo from docker-compose |
| Type errors cascade from `_id``id` rename | Fix systematically: models first, then services/routes |
| Backfill scripts break (they import mongoose) | Keep backfill dir outside tsconfig compilation scope |
| Auth fallback to Mongo breaks login | Auth already has PG path; remove fallback gate |
| Chat reads fail (JSONB shim) | JSONB shim already works; normalization is future work |
---
## Acceptance Criteria
- [ ] `grep -r "mongoose" backend/src/ --include="*.ts"` returns zero hits (excluding backfill archive)
- [ ] `grep -r "Types.ObjectId\|Schema.Types.ObjectId" backend/src/` returns zero hits
- [ ] `grep -r "mongodb" backend/package.json` returns zero hits
- [ ] `grep -r "MONGODB_URI\|MONGO_CONNECT_MODE" backend/src/` returns zero hits
- [ ] `npm run tsc` exits 0
- [ ] Backend starts with `MONGO_CONNECT_MODE=never` (or removed) and `REPO_*=pg` (or removed)
- [ ] Seed scripts populate Postgres successfully
- [ ] All docker-compose files have no `mongodb` service